summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro29
-rw-r--r--src/plugins/platforms/cocoa/main.mm74
-rw-r--r--src/plugins/platforms/cocoa/qcocoaautoreleasepool.h57
-rw-r--r--src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm52
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventloopintegration.h65
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm112
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h99
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm132
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h75
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm110
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindowsurface.h73
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindowsurface.mm103
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h79
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm211
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h61
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm73
-rw-r--r--src/plugins/platforms/directfb/directfb.pro35
-rw-r--r--src/plugins/platforms/directfb/main.cpp72
-rw-r--r--src/plugins/platforms/directfb/qdirectfbblitter.cpp155
-rw-r--r--src/plugins/platforms/directfb/qdirectfbblitter.h76
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp376
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.h84
-rw-r--r--src/plugins/platforms/directfb/qdirectfbcursor.cpp80
-rw-r--r--src/plugins/platforms/directfb/qdirectfbcursor.h63
-rw-r--r--src/plugins/platforms/directfb/qdirectfbglcontext.cpp101
-rw-r--r--src/plugins/platforms/directfb/qdirectfbglcontext.h69
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.cpp208
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.h86
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.cpp144
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.h104
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.cpp191
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.h79
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp141
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindowsurface.h77
-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/qeglplatformcontext.h71
-rw-r--r--src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp184
-rw-r--r--src/plugins/platforms/eglconvenience/qxlibeglintegration.h53
-rw-r--r--src/plugins/platforms/eglconvenience/xlibeglintegration.pri7
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pro31
-rw-r--r--src/plugins/platforms/eglfs/main.cpp72
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp109
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h77
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp244
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h80
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp87
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h68
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindowsurface.cpp101
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindowsurface.h67
-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.pri86
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp328
-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.cpp601
-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/fontdatabases/genericunix/qgenericunixfontdatabase.h53
-rw-r--r--src/plugins/platforms/glxconvenience/glxconvenience.pri7
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.cpp243
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.h56
-rw-r--r--src/plugins/platforms/linuxfb/linuxfb.pro13
-rw-r--r--src/plugins/platforms/linuxfb/main.cpp72
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp875
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h135
-rw-r--r--src/plugins/platforms/minimal/main.cpp73
-rw-r--r--src/plugins/platforms/minimal/minimal.pro13
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.cpp82
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.h86
-rw-r--r--src/plugins/platforms/minimal/qminimalwindowsurface.cpp86
-rw-r--r--src/plugins/platforms/minimal/qminimalwindowsurface.h67
-rw-r--r--src/plugins/platforms/openkode/main.cpp72
-rw-r--r--src/plugins/platforms/openkode/openkode.pro42
-rw-r--r--src/plugins/platforms/openkode/openkodekeytranslator.h244
-rw-r--r--src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp128
-rw-r--r--src/plugins/platforms/openkode/qopenkodeeventloopintegration.h71
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.cpp247
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.h120
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.cpp315
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.h89
-rw-r--r--src/plugins/platforms/openkode/resources.qrc6
-rw-r--r--src/plugins/platforms/openkode/shaders/frag.glslf49
-rw-r--r--src/plugins/platforms/openkode/shaders/vert.glslv55
-rw-r--r--src/plugins/platforms/openvglite/main.cpp71
-rw-r--r--src/plugins/platforms/openvglite/openvglite.pro12
-rw-r--r--src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp193
-rw-r--r--src/plugins/platforms/openvglite/qgraphicssystem_vglite.h93
-rw-r--r--src/plugins/platforms/openvglite/qwindowsurface_vglite.cpp131
-rw-r--r--src/plugins/platforms/openvglite/qwindowsurface_vglite.h91
-rw-r--r--src/plugins/platforms/platforms.pro8
-rw-r--r--src/plugins/platforms/qvfb/main.cpp73
-rw-r--r--src/plugins/platforms/qvfb/qvfb.pro13
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.cpp448
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.h100
-rw-r--r--src/plugins/platforms/qvfb/qvfbwindowsurface.cpp108
-rw-r--r--src/plugins/platforms/qvfb/qvfbwindowsurface.h80
-rw-r--r--src/plugins/platforms/uikit/README45
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/main.mm78
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qml/main.qml112
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp110
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp196
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h80
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist28
-rwxr-xr-xsrc/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj491
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch8
-rw-r--r--src/plugins/platforms/uikit/main.mm74
-rw-r--r--src/plugins/platforms/uikit/quikiteventloop.h72
-rw-r--r--src/plugins/platforms/uikit/quikiteventloop.mm179
-rw-r--r--src/plugins/platforms/uikit/quikitintegration.h72
-rw-r--r--src/plugins/platforms/uikit/quikitintegration.mm104
-rw-r--r--src/plugins/platforms/uikit/quikitscreen.h75
-rw-r--r--src/plugins/platforms/uikit/quikitscreen.mm84
-rw-r--r--src/plugins/platforms/uikit/quikitsoftwareinputhandler.h61
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.h122
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.mm375
-rw-r--r--src/plugins/platforms/uikit/quikitwindowsurface.h64
-rw-r--r--src/plugins/platforms/uikit/quikitwindowsurface.mm96
-rw-r--r--src/plugins/platforms/uikit/uikit.pro27
-rw-r--r--src/plugins/platforms/vnc/main.cpp73
-rw-r--r--src/plugins/platforms/vnc/qvnccursor.cpp156
-rw-r--r--src/plugins/platforms/vnc/qvnccursor.h76
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp251
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h110
-rw-r--r--src/plugins/platforms/vnc/qvncserver.cpp1935
-rw-r--r--src/plugins/platforms/vnc/qvncserver.h533
-rw-r--r--src/plugins/platforms/vnc/vnc.pro22
-rw-r--r--src/plugins/platforms/wayland/gl_integration/gl_integration.pri57
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp52
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h62
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp184
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h69
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp174
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h80
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp112
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h82
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp76
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h66
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri14
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp163
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h79
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp97
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h80
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp73
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri12
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h57
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp95
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h73
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp112
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h71
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp126
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h80
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri12
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp169
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h82
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp139
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h98
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp77
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri15
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp150
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h85
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp126
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h93
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp77
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri13
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp59
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h62
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h145
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c59
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri9
-rw-r--r--src/plugins/platforms/wayland/main.cpp75
-rw-r--r--src/plugins/platforms/wayland/qwaylandbuffer.h60
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.cpp191
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.h60
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp270
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h134
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp337
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h101
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp127
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h76
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.cpp107
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.h77
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.cpp145
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.h83
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.cpp71
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.h58
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp158
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h93
-rw-r--r--src/plugins/platforms/wayland/wayland.pro39
-rw-r--r--src/plugins/platforms/xcb/README3
-rw-r--r--src/plugins/platforms/xcb/main.cpp72
-rw-r--r--src/plugins/platforms/xcb/qdri2context.cpp271
-rw-r--r--src/plugins/platforms/xcb/qdri2context.h77
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp154
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h78
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp780
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h331
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp151
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h83
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp973
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h82
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp185
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h75
-rw-r--r--src/plugins/platforms/xcb/qxcbobject.h62
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp134
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h80
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp683
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h108
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.cpp258
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.h72
-rw-r--r--src/plugins/platforms/xcb/xcb.pro70
-rw-r--r--src/plugins/platforms/xlib/main.cpp79
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.cpp160
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.h85
-rw-r--r--src/plugins/platforms/xlib/qxlibclipboard.cpp677
-rw-r--r--src/plugins/platforms/xlib/qxlibclipboard.h94
-rw-r--r--src/plugins/platforms/xlib/qxlibcursor.cpp200
-rw-r--r--src/plugins/platforms/xlib/qxlibcursor.h68
-rw-r--r--src/plugins/platforms/xlib/qxlibdisplay.cpp78
-rw-r--r--src/plugins/platforms/xlib/qxlibdisplay.h63
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.cpp173
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.h90
-rw-r--r--src/plugins/platforms/xlib/qxlibkeyboard.cpp1001
-rw-r--r--src/plugins/platforms/xlib/qxlibkeyboard.h76
-rw-r--r--src/plugins/platforms/xlib/qxlibmime.cpp322
-rw-r--r--src/plugins/platforms/xlib/qxlibmime.h67
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.cpp133
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.h75
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.cpp488
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.h112
-rw-r--r--src/plugins/platforms/xlib/qxlibstatic.cpp512
-rw-r--r--src/plugins/platforms/xlib/qxlibstatic.h413
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.cpp737
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.h145
-rw-r--r--src/plugins/platforms/xlib/qxlibwindowsurface.cpp224
-rw-r--r--src/plugins/platforms/xlib/qxlibwindowsurface.h86
-rw-r--r--src/plugins/platforms/xlib/xlib.pro62
246 files changed, 34780 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
new file mode 100644
index 0000000000..1633ee45c7
--- /dev/null
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -0,0 +1,29 @@
+TARGET = qcocoa
+include(../../qpluginbase.pri)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+OBJECTIVE_SOURCES = main.mm \
+ qcocoaintegration.mm \
+ qcocoawindowsurface.mm \
+ qcocoawindow.mm \
+ qnsview.mm \
+ qcocoaeventloopintegration.mm \
+ qcocoaautoreleasepool.mm \
+ qnswindowdelegate.mm
+
+OBJECTIVE_HEADERS = qcocoaintegration.h \
+ qcocoawindowsurface.h \
+ qcocoawindow.h \
+ qnsview.h \
+ qcocoaeventloopintegration.h \
+ qcocoaautoreleasepool.h \
+ qnswindowdelegate.h
+
+#add libz for freetype.
+LIBS += -lz
+LIBS += -framework cocoa
+
+include(../fontdatabases/coretext/coretext.pri)
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
+
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
new file mode 100644
index 0000000000..da7af3ff83
--- /dev/null
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -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$
+** 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 <Cocoa/Cocoa.h>
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "qcocoaintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QCocoaIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "Cocoa";
+ return list;
+}
+
+QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "cocoa")
+ return new QCocoaIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(Cocoa, QCocoaIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
new file mode 100644
index 0000000000..6e41e9a38a
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** 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 QCOCOAAUTORELEASEPOOL_H
+#define QCOCOAAUTORELEASEPOOL_H
+
+#include <Cocoa/Cocoa.h>
+
+class QCocoaAutoReleasePool
+{
+public:
+ QCocoaAutoReleasePool();
+ ~QCocoaAutoReleasePool();
+
+private:
+ NSAutoreleasePool *pool;
+};
+
+#endif // QCOCOAAUTORELEASEPOOL_H
diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm
new file mode 100644
index 0000000000..35750cda52
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 "qcocoaautoreleasepool.h"
+
+QCocoaAutoReleasePool::QCocoaAutoReleasePool()
+{
+ pool = [[NSAutoreleasePool alloc] init];
+}
+
+QCocoaAutoReleasePool::~QCocoaAutoReleasePool()
+{
+ [pool release];
+}
diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h
new file mode 100644
index 0000000000..81e272ec1b
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 QCOCAEVENTLOOPINTEGRATION_H
+#define QCOCAEVENTLOOPINTEGRATION_H
+
+#include <Cocoa/Cocoa.h>
+
+#include <QPlatformEventLoopIntegration>
+
+
+class QCocoaEventLoopIntegration : public QPlatformEventLoopIntegration
+{
+public:
+ QCocoaEventLoopIntegration();
+ void startEventLoop();
+ void quitEventLoop();
+ void qtNeedsToProcessEvents();
+
+private:
+ CFRunLoopSourceContext m_sourceContext;
+ CFRunLoopTimerContext m_timerContext;
+ CFRunLoopSourceRef m_source;
+};
+
+#endif // QCOCAEVENTLOOPINTEGRATION_H
+
diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm
new file mode 100644
index 0000000000..885916ed74
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 "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/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
new file mode 100644
index 0000000000..2a04e8c2ed
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 QPLATFORMINTEGRATION_COCOA_H
+#define QPLATFORMINTEGRATION_COCOA_H
+
+#include <Cocoa/Cocoa.h>
+
+#include "qcocoaautoreleasepool.h"
+
+#include <QtGui/QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaScreen : public QPlatformScreen
+{
+public:
+ QCocoaScreen(int screenIndex);
+ ~QCocoaScreen();
+
+ QRect geometry() const { return m_geometry; }
+ int depth() const { return m_depth; }
+ QImage::Format format() const { return m_format; }
+ QSize physicalSize() const { return m_physicalSize; }
+
+public:
+ NSScreen *m_screen;
+ QRect m_geometry;
+ int m_depth;
+ QImage::Format m_format;
+ QSize m_physicalSize;
+};
+
+class QCocoaIntegration : public QPlatformIntegration
+{
+public:
+ QCocoaIntegration();
+ ~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; }
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+ QPlatformEventLoopIntegration *createEventLoopIntegration() const;
+
+private:
+ QList<QPlatformScreen *> mScreens;
+ QPlatformFontDatabase *mFontDb;
+
+ QCocoaAutoReleasePool *mPool;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
new file mode 100644
index 0000000000..7c4319c5e7
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** 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 "qcocoaintegration.h"
+
+#include "qcocoawindow.h"
+#include "qcocoawindowsurface.h"
+#include "qcocoaeventloopintegration.h"
+
+#include "qcoretextfontdatabase.h"
+
+#include <QtGui/QApplication>
+
+#include <private/qpixmap_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QCocoaScreen::QCocoaScreen(int screenIndex)
+ :QPlatformScreen()
+{
+ m_screen = [[NSScreen screens] objectAtIndex:screenIndex];
+ NSRect rect = [m_screen frame];
+ m_geometry = QRect(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
+
+ m_format = QImage::Format_ARGB32;
+
+ m_depth = NSBitsPerPixelFromDepth([m_screen depth]);
+
+ const int dpi = 72;
+ const qreal inch = 25.4;
+ m_physicalSize = QSize(qRound(m_geometry.width() * inch / dpi), qRound(m_geometry.height() *inch / dpi));
+}
+
+QCocoaScreen::~QCocoaScreen()
+{
+}
+
+QCocoaIntegration::QCocoaIntegration()
+ : mFontDb(new QCoreTextFontDatabase())
+{
+ mPool = new QCocoaAutoReleasePool;
+
+ //Make sure we have a nsapplication :)
+ [NSApplication sharedApplication];
+// [[OurApplication alloc] init];
+
+ NSArray *screens = [NSScreen screens];
+ for (uint i = 0; i < [screens count]; i++) {
+ QCocoaScreen *screen = new QCocoaScreen(i);
+ mScreens.append(screen);
+ }
+}
+
+QCocoaIntegration::~QCocoaIntegration()
+{
+ delete mPool;
+}
+
+bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+
+
+QPixmapData *QCocoaIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QCocoaWindow(widget);
+}
+
+QWindowSurface *QCocoaIntegration::createWindowSurface(QWidget *widget, WId winId) const
+{
+ return new QCocoaWindowSurface(widget,winId);
+}
+
+QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
+QPlatformEventLoopIntegration *QCocoaIntegration::createEventLoopIntegration() const
+{
+ return new QCocoaEventLoopIntegration();
+}
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
new file mode 100644
index 0000000000..b71879de41
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoawindow.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$
+** 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 QCOCOAWINDOW_H
+#define QCOCOAWINDOW_H
+
+#include <Cocoa/Cocoa.h>
+
+#include <QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaWindow : public QPlatformWindow
+{
+public:
+ QCocoaWindow(QWidget *tlw);
+ ~QCocoaWindow();
+
+ void setGeometry(const QRect &rect);
+
+ void setVisible(bool visible);
+
+ WId winId() const;
+
+ NSView *contentView() const;
+ void setContentView(NSView *contentView);
+
+ void windowDidResize();
+
+private:
+ NSWindow *m_nsWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOCOAWINDOW_H
+
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
new file mode 100644
index 0000000000..aa54fe90ad
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** 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 "qcocoawindow.h"
+#include "qnswindowdelegate.h"
+#include "qcocoaautoreleasepool.h"
+
+#include <QWidget>
+
+#include <QtGui/QApplication>
+
+#include <QWindowSystemInterface>
+
+#include <QDebug>
+
+QCocoaWindow::QCocoaWindow(QWidget *tlw)
+ : QPlatformWindow(tlw)
+{
+ 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];
+
+ QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
+ [m_nsWindow setDelegate:delegate];
+
+ [m_nsWindow makeKeyAndOrderFront:nil];
+ [m_nsWindow setAcceptsMouseMovedEvents:YES];
+}
+
+QCocoaWindow::~QCocoaWindow()
+{
+}
+
+void QCocoaWindow::setGeometry(const QRect &rect)
+{
+ QPlatformWindow::setGeometry(rect);
+
+ NSRect bounds = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+ [[m_nsWindow contentView]setFrameSize:bounds.size];
+}
+
+void QCocoaWindow::setVisible(bool visible)
+{
+ Q_UNUSED(visible);
+}
+
+WId QCocoaWindow::winId() const
+{
+ return WId([m_nsWindow windowNumber]);
+}
+
+NSView *QCocoaWindow::contentView() const
+{
+ return [m_nsWindow contentView];
+}
+
+void QCocoaWindow::setContentView(NSView *contentView)
+{
+ [m_nsWindow setContentView:contentView];
+}
+
+void QCocoaWindow::windowDidResize()
+{
+ //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing...
+ NSRect rect = [[m_nsWindow contentView]frame];
+ QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
+ QWindowSystemInterface::handleGeometryChange(widget(),geo);
+}
diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.h b/src/plugins/platforms/cocoa/qcocoawindowsurface.h
new file mode 100644
index 0000000000..5ae7be197d
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoawindowsurface.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 QWINDOWSURFACE_COCOA_H
+#define QWINDOWSURFACE_COCOA_H
+
+#include <Cocoa/Cocoa.h>
+
+#include "qcocoawindow.h"
+#include "qnsview.h"
+
+#include <QtGui/private/qwindowsurface_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaWindowSurface : public QWindowSurface
+{
+public:
+ QCocoaWindowSurface(QWidget *window, WId wid);
+ ~QCocoaWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize (const QSize &size);
+
+private:
+
+ QCocoaWindow *m_cocoaWindow;
+ QImage *m_image;
+ QNSView *m_contentView;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.mm b/src/plugins/platforms/cocoa/qcocoawindowsurface.mm
new file mode 100644
index 0000000000..ecf6879c67
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoawindowsurface.mm
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** 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 "qcocoawindowsurface.h"
+
+#include <QtCore/qdebug.h>
+
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+QRect flipedRect(const QRect &sourceRect,int height)
+{
+ if (!sourceRect.isValid())
+ return QRect();
+ QRect flippedRect = sourceRect;
+ flippedRect.moveTop(height - sourceRect.y());
+ return flippedRect;
+}
+
+QCocoaWindowSurface::QCocoaWindowSurface(QWidget *window, WId wId)
+ : QWindowSurface(window)
+{
+ m_cocoaWindow = static_cast<QCocoaWindow *>(window->platformWindow());
+
+ 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);
+}
+
+QCocoaWindowSurface::~QCocoaWindowSurface()
+{
+ delete m_image;
+}
+
+QPaintDevice *QCocoaWindowSurface::paintDevice()
+{
+ return m_image;
+}
+
+void QCocoaWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(offset);
+
+ QRect geo = region.boundingRect();
+
+ NSRect rect = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
+ [m_contentView displayRect:rect];
+}
+
+void QCocoaWindowSurface::resize(const QSize &size)
+{
+ 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];
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
new file mode 100644
index 0000000000..fc946e2f29
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 QNSVIEW_H
+#define QNSVIEW_H
+
+#include <Cocoa/Cocoa.h>
+
+#include <QtGui/QImage>
+
+@interface QNSView : NSView {
+ CGImageRef m_cgImage;
+ QWidget *m_widget;
+ Qt::MouseButtons m_buttons;
+}
+
+- (id)init;
+- (id)initWithWidget:(QWidget *)widget;
+
+- (void)setImage:(QImage *)image;
+- (void)drawRect:(NSRect)dirtyRect;
+
+- (BOOL)isFlipped;
+
+- (void)handleMouseEvent:(NSEvent *)theEvent;
+- (void)mouseDown:(NSEvent *)theEvent;
+- (void)mouseDragged:(NSEvent *)theEvent;
+- (void)mouseUp:(NSEvent *)theEvent;
+- (void)mouseMoved:(NSEvent *)theEvent;
+- (void)mouseEntered:(NSEvent *)theEvent;
+- (void)mouseExited:(NSEvent *)theEvent;
+- (void)rightMouseDown:(NSEvent *)theEvent;
+- (void)rightMouseDragged:(NSEvent *)theEvent;
+- (void)rightMouseUp:(NSEvent *)theEvent;
+- (void)otherMouseDown:(NSEvent *)theEvent;
+- (void)otherMouseDragged:(NSEvent *)theEvent;
+- (void)otherMouseUp:(NSEvent *)theEvent;
+
+@end
+
+#endif //QNSVIEW_H
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
new file mode 100644
index 0000000000..6fda27b352
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** 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 "qnsview.h"
+
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QDebug>
+
+@implementation QNSView
+
+- (id) init
+{
+ self = [super init];
+ if (self) {
+ m_cgImage = 0;
+ m_widget = 0;
+ m_buttons = Qt::NoButton;
+ }
+ return self;
+}
+
+- (id)initWithWidget:(QWidget *)widget {
+ self = [self init];
+ if (self) {
+ m_widget = widget;
+ }
+ return self;
+}
+
+- (void) setImage:(QImage *)image
+{
+ CGImageRelease(m_cgImage);
+
+ const uchar *imageData = image->bits();
+ int bitDepth = image->depth();
+ int colorBufferSize = 8;
+ int bytesPrLine = image->bytesPerLine();
+ int width = image->width();
+ int height = image->height();
+
+ CGColorSpaceRef cgColourSpaceRef = CGColorSpaceCreateDeviceRGB();
+
+ CGDataProviderRef cgDataProviderRef = CGDataProviderCreateWithData(
+ NULL,
+ imageData,
+ image->byteCount(),
+ NULL);
+
+ m_cgImage = CGImageCreate(width,
+ height,
+ colorBufferSize,
+ bitDepth,
+ bytesPrLine,
+ cgColourSpaceRef,
+ kCGImageAlphaNone,
+ cgDataProviderRef,
+ NULL,
+ false,
+ kCGRenderingIntentDefault);
+
+ CGColorSpaceRelease(cgColourSpaceRef);
+
+}
+
+- (void) drawRect:(NSRect)dirtyRect
+{
+ if (!m_cgImage)
+ return;
+
+ CGRect dirtyCGRect = NSRectToCGRect(dirtyRect);
+
+ NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext];
+ CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort];
+
+ CGContextSaveGState( cgContext );
+ int dy = dirtyCGRect.origin.y + CGRectGetMaxY(dirtyCGRect);
+ CGContextTranslateCTM(cgContext, 0, dy);
+ CGContextScaleCTM(cgContext, 1, -1);
+
+ CGImageRef subImage = CGImageCreateWithImageInRect(m_cgImage, dirtyCGRect);
+ CGContextDrawImage(cgContext,dirtyCGRect,subImage);
+
+ CGContextRestoreGState(cgContext);
+
+ CGImageRelease(subImage);
+
+}
+
+- (BOOL) isFlipped
+{
+ return YES;
+}
+
+- (void)handleMouseEvent:(NSEvent *)theEvent;
+{
+ NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+ QPoint qt_localPoint(point.x,point.y);
+
+ NSTimeInterval timestamp = [theEvent timestamp];
+ ulong qt_timestamp = timestamp * 1000;
+
+ QWindowSystemInterface::handleMouseEvent(m_widget,qt_timestamp,qt_localPoint,QPoint(),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)mouseMoved:(NSEvent *)theEvent
+{
+ qDebug() << "mouseMove";
+ [self handleMouseEvent:theEvent];
+}
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ Q_UNUSED(theEvent);
+ QWindowSystemInterface::handleEnterEvent(m_widget);
+}
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ Q_UNUSED(theEvent);
+ QWindowSystemInterface::handleLeaveEvent(m_widget);
+}
+- (void)rightMouseDown:(NSEvent *)theEvent
+{
+ 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];
+}
+- (void)rightMouseUp:(NSEvent *)theEvent
+{
+ m_buttons &= QFlag(~int(Qt::RightButton));
+ [self handleMouseEvent:theEvent];
+}
+- (void)otherMouseDown:(NSEvent *)theEvent
+{
+ 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];
+}
+- (void)otherMouseUp:(NSEvent *)theEvent
+{
+ m_buttons &= QFlag(~int(Qt::MiddleButton));
+ [self handleMouseEvent:theEvent];
+}
+
+
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
new file mode 100644
index 0000000000..f4dcec73dd
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.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$
+** 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 QNSWINDOWDELEGATE_H
+#define QNSWINDOWDELEGATE_H
+
+#include <Cocoa/Cocoa.h>
+
+#include "qcocoawindow.h"
+
+@interface QNSWindowDelegate : NSObject <NSWindowDelegate>
+{
+ QCocoaWindow *m_cocoaWindow;
+}
+
+- (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow;
+
+- (void)windowDidResize:(NSNotification *)notification;
+- (void)windowWillClose:(NSNotification *)notification;
+
+@end
+
+#endif // QNSWINDOWDELEGATE_H
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
new file mode 100644
index 0000000000..58dffb7c09
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 "qnswindowdelegate.h"
+
+#include <QDebug>
+#include <QWindowSystemInterface>
+
+@implementation QNSWindowDelegate
+
+- (id) initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow
+{
+ self = [super init];
+
+ if (self) {
+ m_cocoaWindow = cocoaWindow;
+ }
+ return self;
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowDidResize();
+ }
+}
+
+- (void)windowWillClose:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ QWindowSystemInterface::handleCloseEvent(m_cocoaWindow->widget());
+}
+
+@end
diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro
new file mode 100644
index 0000000000..65c49e386f
--- /dev/null
+++ b/src/plugins/platforms/directfb/directfb.pro
@@ -0,0 +1,35 @@
+TARGET = qdirectfb
+include(../../qpluginbase.pri)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+isEmpty(DIRECTFB_LIBS) {
+ DIRECTFB_LIBS = -ldirectfb -lfusion -ldirect -lpthread
+}
+isEmpty(DIRECTFB_INCLUDEPATH) {
+ DIRECTFB_INCLUDEPATH = /usr/include/directfb
+}
+
+INCLUDEPATH += $$DIRECTFB_INCLUDEPATH
+LIBS += $$DIRECTFB_LIBS
+
+SOURCES = main.cpp \
+ qdirectfbintegration.cpp \
+ qdirectfbwindowsurface.cpp \
+ qdirectfbblitter.cpp \
+ qdirectfbconvenience.cpp \
+ qdirectfbinput.cpp \
+ qdirectfbcursor.cpp \
+ qdirectfbwindow.cpp \
+ qdirectfbglcontext.cpp
+HEADERS = qdirectfbintegration.h \
+ qdirectfbwindowsurface.h \
+ qdirectfbblitter.h \
+ qdirectfbconvenience.h \
+ qdirectfbinput.h \
+ qdirectfbcursor.h \
+ qdirectfbwindow.h \
+ qdirectfbglcontext.h
+
+include(../fontdatabases/genericunix/genericunix.pri)
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/directfb/main.cpp b/src/plugins/platforms/directfb/main.cpp
new file mode 100644
index 0000000000..d9caa70608
--- /dev/null
+++ b/src/plugins/platforms/directfb/main.cpp
@@ -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$
+** 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 <QtGui/QPlatformIntegrationPlugin>
+#include "qdirectfbintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDirectFbIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QDirectFbIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "directfb";
+ return list;
+}
+
+QPlatformIntegration * QDirectFbIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "directfb")
+ return new QDirectFbIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(directfb, QDirectFbIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.cpp b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
new file mode 100644
index 0000000000..19998ceb2e
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** 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 "qdirectfbblitter.h"
+#include "qdirectfbconvenience.h"
+
+#include <QtGui/private/qpixmap_blitter_p.h>
+
+#include <QDebug>
+
+#include <directfb.h>
+
+QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, IDirectFBSurface *surface)
+ : QBlittable(rect, QBlittable::Capabilities(QBlittable::SolidRectCapability
+ |QBlittable::SourcePixmapCapability
+ |QBlittable::SourceOverPixmapCapability
+ |QBlittable::SourceOverScaledPixmapCapability))
+{
+ if (surface) {
+ m_surface = surface;
+ } else {
+ DFBSurfaceDescription surfaceDesc;
+ memset(&surfaceDesc,0,sizeof(DFBSurfaceDescription));
+ surfaceDesc.width = rect.width();
+ surfaceDesc.height = rect.height();
+ surfaceDesc.caps = DSCAPS_PREMULTIPLIED;
+ surfaceDesc.pixelformat = DSPF_ARGB;
+ surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT);
+
+ IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
+ dfb->CreateSurface(dfb,&surfaceDesc, &m_surface);
+ m_surface->Clear(m_surface,0,0,0,0);
+ }
+
+}
+
+QDirectFbBlitter::~QDirectFbBlitter()
+{
+ unlock();
+ m_surface->Release(m_surface);
+}
+
+void QDirectFbBlitter::fillRect(const QRectF &rect, const QColor &color)
+{
+ m_surface->SetColor(m_surface, color.red(), color.green(), color.blue(), color.alpha());
+// When the blitter api supports non opaque blits, also remember to change
+// qpixmap_blitter.cpp::fill
+// DFBSurfaceDrawingFlags drawingFlags = color.alpha() ? DSDRAW_BLEND : DSDRAW_NOFX;
+// m_surface->SetDrawingFlags(m_surface, drawingFlags);
+ m_surface->SetDrawingFlags(m_surface, DSDRAW_NOFX);
+ m_surface->FillRectangle(m_surface, rect.x(), rect.y(),
+ rect.width(), rect.height());
+}
+
+void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &srcRect)
+{
+ QPixmapData *data = pixmap.pixmapData();
+ Q_ASSERT(data->width() && data->height());
+ Q_ASSERT(data->classId() == QPixmapData::BlitterClass);
+ QBlittablePixmapData *blitPm = static_cast<QBlittablePixmapData*>(data);
+ QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blitPm->blittable());
+ dfbBlitter->unlock();
+
+ IDirectFBSurface *s = dfbBlitter->m_surface;
+
+ DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX;
+ DFBSurfacePorterDuffRule porterDuff = DSPD_SRC;
+ if (pixmap.hasAlpha()) {
+ blittingFlags = DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuff = DSPD_SRC_OVER;
+ }
+
+ m_surface->SetBlittingFlags(m_surface, DFBSurfaceBlittingFlags(blittingFlags));
+ m_surface->SetPorterDuff(m_surface,porterDuff);
+ m_surface->SetDstBlendFunction(m_surface,DSBF_INVSRCALPHA);
+
+ const DFBRectangle sRect = { srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height() };
+
+ DFBResult result;
+ if (rect.width() == srcRect.width() && rect.height() == srcRect.height())
+ result = m_surface->Blit(m_surface, s, &sRect, rect.x(), rect.y());
+ else {
+ const DFBRectangle dRect = { rect.x(), rect.y(), rect.width(), rect.height() };
+ result = m_surface->StretchBlit(m_surface, s, &sRect, &dRect);
+ }
+ if (result != DFB_OK)
+ DirectFBError("QDirectFBBlitter::drawPixmap()", result);
+}
+
+QImage *QDirectFbBlitter::doLock()
+{
+ Q_ASSERT(m_surface);
+ Q_ASSERT(size().isValid());
+
+ void *mem;
+ int bpl;
+ const DFBResult result = m_surface->Lock(m_surface, DFBSurfaceLockFlags(DSLF_WRITE|DSLF_READ), static_cast<void**>(&mem), &bpl);
+ if (result == DFB_OK) {
+ DFBSurfacePixelFormat dfbFormat;
+ DFBSurfaceCapabilities dfbCaps;
+ m_surface->GetPixelFormat(m_surface,&dfbFormat);
+ m_surface->GetCapabilities(m_surface,&dfbCaps);
+ QImage::Format format = QDirectFbConvenience::imageFormatFromSurfaceFormat(dfbFormat, dfbCaps);
+ int w, h;
+ m_surface->GetSize(m_surface,&w,&h);
+ m_image = QImage(static_cast<uchar *>(mem),w,h,bpl,format);
+ } else {
+ DirectFBError("Failed to lock image", result);
+ }
+
+ return &m_image;
+}
+
+void QDirectFbBlitter::doUnlock()
+{
+ m_surface->Unlock(m_surface);
+}
diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.h b/src/plugins/platforms/directfb/qdirectfbblitter.h
new file mode 100644
index 0000000000..bd5dbdac10
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbblitter.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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 QDIRECTFBBLITTER_H
+#define QDIRECTFBBLITTER_H
+
+#include "qdirectfbconvenience.h"
+
+#include <private/qblittable_p.h>
+
+#include <directfb.h>
+
+class QDirectFbBlitter : public QBlittable
+{
+public:
+ QDirectFbBlitter(const QSize &size, IDirectFBSurface *surface = 0);
+ virtual ~QDirectFbBlitter();
+
+ virtual void fillRect(const QRectF &rect, const QColor &color);
+ virtual void drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &subrect);
+
+protected:
+ virtual QImage *doLock();
+ virtual void doUnlock();
+
+ IDirectFBSurface *m_surface;
+ QImage m_image;
+
+ friend class QDirectFbConvenience;
+};
+
+class QDirectFbBlitterPixmapData : public QBlittablePixmapData
+{
+public:
+ QBlittable *createBlittable(const QSize &size) const { return new QDirectFbBlitter(size); }
+};
+
+#endif // QDIRECTFBBLITTER_H
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
new file mode 100644
index 0000000000..01cef83adf
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -0,0 +1,376 @@
+/****************************************************************************
+**
+** 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 "qdirectfbconvenience.h"
+#include "qdirectfbblitter.h"
+
+#include <private/qpixmap_blitter_p.h>
+
+IDirectFB *QDirectFbConvenience::dfbInterface()
+{
+ static IDirectFB *dfb = 0;
+ if (!dfb) {
+ DFBResult result = DirectFBCreate(&dfb);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBConvenience: error creating DirectFB interface",result);
+ return 0;
+ }
+ }
+ return dfb;
+}
+
+IDirectFBDisplayLayer *QDirectFbConvenience::dfbDisplayLayer(int display)
+{
+ IDirectFBDisplayLayer *layer;
+ DFBResult result = QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),display,&layer);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFbConvenience: "
+ "Unable to get primary display layer!", result);
+ }
+ return layer;
+}
+
+QImage::Format QDirectFbConvenience::imageFormatFromSurfaceFormat(const DFBSurfacePixelFormat format, const DFBSurfaceCapabilities caps)
+{
+ switch (format) {
+ case DSPF_LUT8:
+ return QImage::Format_Indexed8;
+ case DSPF_RGB24:
+ return QImage::Format_RGB888;
+ case DSPF_ARGB4444:
+ return QImage::Format_ARGB4444_Premultiplied;
+ case DSPF_RGB444:
+ return QImage::Format_RGB444;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ return QImage::Format_RGB555;
+ case DSPF_RGB16:
+ return QImage::Format_RGB16;
+ case DSPF_ARGB6666:
+ return QImage::Format_ARGB6666_Premultiplied;
+ case DSPF_RGB18:
+ return QImage::Format_RGB666;
+ case DSPF_RGB32:
+ return QImage::Format_RGB32;
+ case DSPF_ARGB: {
+ if (caps & DSCAPS_PREMULTIPLIED)
+ return QImage::Format_ARGB32_Premultiplied;
+ else return QImage::Format_ARGB32; }
+ default:
+ break;
+ }
+ return QImage::Format_Invalid;
+
+}
+
+int QDirectFbConvenience::colorDepthForSurface(const DFBSurfacePixelFormat format)
+{
+ return ((0x1f << 7) & format) >> 7;
+}
+
+IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPixmapData(QPixmapData *pixmapData)
+{
+ QBlittablePixmapData *blittablePmData = static_cast<QBlittablePixmapData *>(pixmapData);
+ if (blittablePmData) {
+ QBlittable *blittable = blittablePmData->blittable();
+ QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blittable);
+ return dfbBlitter->m_surface;
+ }
+ return 0;
+}
+
+Qt::MouseButton QDirectFbConvenience::mouseButton(DFBInputDeviceButtonIdentifier identifier)
+{
+ switch (identifier){
+ case DIBI_LEFT:
+ return Qt::LeftButton;
+ case DIBI_MIDDLE:
+ return Qt::MidButton;
+ case DIBI_RIGHT:
+ return Qt::RightButton;
+ default:
+ return Qt::NoButton;
+ }
+}
+
+Qt::MouseButtons QDirectFbConvenience::mouseButtons(DFBInputDeviceButtonMask mask)
+{
+ Qt::MouseButtons buttons = Qt::NoButton;
+
+ if (mask & DIBM_LEFT) {
+ buttons |= Qt::LeftButton;
+ }
+ if (mask & DIBM_MIDDLE) {
+ buttons |= Qt::MidButton;
+ }
+ if (mask & DIBM_RIGHT) {
+ buttons |= Qt::RightButton;
+ }
+ return buttons;
+}
+
+Qt::KeyboardModifiers QDirectFbConvenience::keyboardModifiers(DFBInputDeviceModifierMask mask)
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+
+ if (mask & DIMM_SHIFT) {
+ modifiers |= Qt::ShiftModifier;
+ }
+ if (mask & DIMM_ALT) {
+ modifiers |= Qt::AltModifier;
+ }
+ if (mask & DIMM_ALTGR) {
+ modifiers |= Qt::MetaModifier;
+ }
+ if (mask & DIMM_CONTROL) {
+ modifiers |= Qt::ControlModifier;
+ }
+ if (mask & DIMM_META) {
+ modifiers | Qt::MetaModifier;
+ }
+ return modifiers;
+}
+
+QEvent::Type QDirectFbConvenience::eventType(DFBWindowEventType type)
+{
+ switch(type) {
+ case DWET_BUTTONDOWN:
+ return QEvent::MouseButtonPress;
+ case DWET_BUTTONUP:
+ return QEvent::MouseButtonRelease;
+ case DWET_MOTION:
+ return QEvent::MouseMove;
+ case DWET_WHEEL:
+ return QEvent::Wheel;
+ case DWET_KEYDOWN:
+ return QEvent::KeyPress;
+ case DWET_KEYUP:
+ return QEvent::KeyRelease;
+ default:
+ return QEvent::None;
+ }
+}
+QDirectFbKeyMap *QDirectFbConvenience::dfbKeymap = 0;
+QDirectFbKeyMap *QDirectFbConvenience::keyMap()
+{
+ if (!dfbKeymap)
+ dfbKeymap = new QDirectFbKeyMap();
+ return dfbKeymap;
+}
+
+QDirectFbKeyMap::QDirectFbKeyMap()
+{
+ 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);
+}
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.h b/src/plugins/platforms/directfb/qdirectfbconvenience.h
new file mode 100644
index 0000000000..e85c5029e2
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 QDIRECTFBCONVENIENCE_H
+#define QDIRECTFBCONVENIENCE_H
+
+#include <QtGui/qimage.h>
+#include <QtCore/QHash>
+#include <QtCore/QEvent>
+#include <QtGui/QPixmap>
+
+#include <directfb.h>
+
+class QDirectFbKeyMap: public QHash<DFBInputDeviceKeySymbol, Qt::Key>
+{
+public:
+ QDirectFbKeyMap();
+};
+
+
+class QDirectFbConvenience
+{
+public:
+ static QImage::Format imageFormatFromSurfaceFormat(const DFBSurfacePixelFormat format, const DFBSurfaceCapabilities caps);
+ static bool pixelFomatHasAlpha(const DFBSurfacePixelFormat format) { return (1 << 16) & format; }
+ static int colorDepthForSurface(const DFBSurfacePixelFormat format);
+
+ //This is set by the graphicssystem constructor
+ static IDirectFB *dfbInterface();
+ static IDirectFBDisplayLayer *dfbDisplayLayer(int display = DLID_PRIMARY);
+
+ static IDirectFBSurface *dfbSurfaceForPixmapData(QPixmapData *);
+
+ static Qt::MouseButton mouseButton(DFBInputDeviceButtonIdentifier identifier);
+ static Qt::MouseButtons mouseButtons(DFBInputDeviceButtonMask mask);
+ static Qt::KeyboardModifiers keyboardModifiers(DFBInputDeviceModifierMask mask);
+ static QEvent::Type eventType(DFBWindowEventType type);
+
+ static QDirectFbKeyMap *keyMap();
+
+private:
+ static QDirectFbKeyMap *dfbKeymap;
+ friend class QDirectFbIntegration;
+};
+
+#endif // QDIRECTFBCONVENIENCE_H
diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.cpp b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
new file mode 100644
index 0000000000..3cd81acbd3
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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 "qdirectfbcursor.h"
+#include "qdirectfbconvenience.h"
+
+
+QDirectFBCursor::QDirectFBCursor(QPlatformScreen* screen) :
+ QPlatformCursor(screen), surface(0)
+{
+ QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),DLID_PRIMARY, &m_layer);
+ image = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
+}
+
+void QDirectFBCursor::changeCursor(QCursor * cursor, QWidget * widget)
+{
+ 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();
+ map = QPixmap::fromImage(*i);
+ } else {
+ QPoint point = cursor->hotSpot();
+ xSpot = point.x();
+ ySpot = point.y();
+ map = cursor->pixmap();
+ }
+
+ IDirectFBSurface *surface = QDirectFbConvenience::dfbSurfaceForPixmapData(map.pixmapData());
+
+ if (m_layer->SetCooperativeLevel(m_layer, DLSCL_ADMINISTRATIVE) != DFB_OK) {
+ return;
+ }
+ m_layer->SetCursorShape( m_layer, surface, xSpot, ySpot);
+ m_layer->SetCooperativeLevel(m_layer, DLSCL_SHARED);
+}
diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.h b/src/plugins/platforms/directfb/qdirectfbcursor.h
new file mode 100644
index 0000000000..f37bbedde1
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbcursor.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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 QDIRECTFBCURSOR_H
+#define QDIRECTFBCURSOR_H
+
+#include <QPlatformCursor>
+#include <directfb.h>
+class QDirectFbScreen;
+class QDirectFbBlitter;
+
+class QDirectFBCursor : public QPlatformCursor
+{
+public:
+ QDirectFBCursor(QPlatformScreen *screem);
+ void changeCursor(QCursor * cursor, QWidget * widget);
+
+private:
+ IDirectFBDisplayLayer * m_layer;
+ IDirectFBSurface * surface;
+ QPlatformCursorImage * image;
+ QDirectFbBlitter *blitter;
+};
+
+#endif // QDIRECTFBCURSOR_H
diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
new file mode 100644
index 0000000000..85effc9446
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 "qdirectfbglcontext.h"
+
+#include <directfb/directfbgl.h>
+
+#include <QDebug>
+
+QDirectFbGLContext::QDirectFbGLContext(IDirectFBGL *glContext)
+ : m_dfbGlContext(glContext)
+{
+ DFBResult result;
+ DFBGLAttributes glAttribs;
+ result = m_dfbGlContext->GetAttributes(glContext, &glAttribs);
+ if (result == DFB_OK) {
+ m_windowFormat.setDepthBufferSize(glAttribs.depth_size);
+ m_windowFormat.setStencilBufferSize(glAttribs.stencil_size);
+
+ m_windowFormat.setRedBufferSize(glAttribs.red_size);
+ m_windowFormat.setGreenBufferSize(glAttribs.green_size);
+ m_windowFormat.setBlueBufferSize(glAttribs.blue_size);
+ m_windowFormat.setAlphaBufferSize(glAttribs.alpha_size);
+
+ m_windowFormat.setAccumBufferSize(glAttribs.accum_red_size);
+ m_windowFormat.setAlpha(glAttribs.accum_alpha_size);
+
+ m_windowFormat.setDoubleBuffer(glAttribs.double_buffer);
+ m_windowFormat.setStereo(glAttribs.stereo);
+ }
+}
+
+void QDirectFbGLContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+ m_dfbGlContext->Lock(m_dfbGlContext);
+}
+
+void QDirectFbGLContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ m_dfbGlContext->Unlock(m_dfbGlContext);
+}
+
+void *QDirectFbGLContext::getProcAddress(const QString &procName)
+{
+ void *proc;
+ DFBResult result = m_dfbGlContext->GetProcAddress(m_dfbGlContext,qPrintable(procName),&proc);
+ if (result == DFB_OK)
+ return proc;
+ return 0;
+}
+
+void QDirectFbGLContext::swapBuffers()
+{
+// m_dfbGlContext->Unlock(m_dfbGlContext); //maybe not in doneCurrent()
+ qDebug() << "Swap buffers";
+}
+
+QPlatformWindowFormat QDirectFbGLContext::platformWindowFormat() const
+{
+ return m_windowFormat;
+}
diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.h b/src/plugins/platforms/directfb/qdirectfbglcontext.h
new file mode 100644
index 0000000000..f25b1a7def
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbglcontext.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$
+** 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 QDIRECTFBGLCONTEXT_H
+#define QDIRECTFBGLCONTEXT_H
+
+#include <QPlatformGLContext>
+
+#include "qdirectfbconvenience.h"
+
+class QDirectFbGLContext : public QPlatformGLContext
+{
+public:
+ explicit QDirectFbGLContext(IDirectFBGL *glContext);
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void *getProcAddress(const QString &procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+
+private:
+ IDirectFBGL *m_dfbGlContext;
+
+ QPlatformWindowFormat m_windowFormat;
+
+};
+
+#endif // QDIRECTFBGLCONTEXT_H
diff --git a/src/plugins/platforms/directfb/qdirectfbinput.cpp b/src/plugins/platforms/directfb/qdirectfbinput.cpp
new file mode 100644
index 0000000000..30654bf52e
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbinput.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** 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 "qdirectfbinput.h"
+#include "qdirectfbconvenience.h"
+
+#include <QThread>
+#include <QDebug>
+#include <QWindowSystemInterface>
+#include <QMouseEvent>
+#include <QEvent>
+#include <QApplication>
+
+#include <directfb.h>
+
+QDirectFbInput::QDirectFbInput(QObject *parent)
+ : QObject(parent), m_shouldStop(false)
+{
+ m_dfbInterface = QDirectFbConvenience::dfbInterface();
+
+ DFBResult ok = m_dfbInterface->CreateEventBuffer(m_dfbInterface,&m_eventBuffer);
+ if (ok != DFB_OK)
+ DirectFBError("Failed to initialise eventbuffer", ok);
+
+ m_dfbInterface->GetDisplayLayer(m_dfbInterface,DLID_PRIMARY, &m_dfbDisplayLayer);
+
+}
+
+void QDirectFbInput::runInputEventLoop()
+{
+ while (true) {
+ m_eventBuffer->WaitForEvent(m_eventBuffer);
+ if (m_shouldStop) {
+ m_waitStop.release();
+ break;
+ }
+ handleEvents();
+ }
+}
+
+void QDirectFbInput::stopInputEventLoop()
+{
+ m_shouldStop = true;
+ m_waitStop.acquire();
+}
+
+void QDirectFbInput::addWindow(DFBWindowID id, QWidget *tlw)
+{
+ m_tlwMap.insert(id,tlw);
+ IDirectFBWindow *window;
+ m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,id,&window);
+
+ window->AttachEventBuffer(window,m_eventBuffer);
+}
+
+void QDirectFbInput::removeWindow(WId wId)
+{
+ IDirectFBWindow *window;
+ m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,wId, &window);
+
+ window->DetachEventBuffer(window,m_eventBuffer);
+ m_tlwMap.remove(wId);
+}
+
+void QDirectFbInput::handleEvents()
+{
+ DFBResult hasEvent = m_eventBuffer->HasEvent(m_eventBuffer);
+ while(hasEvent == DFB_OK){
+ DFBEvent event;
+ DFBResult ok = m_eventBuffer->GetEvent(m_eventBuffer,&event);
+ if (ok != DFB_OK)
+ DirectFBError("Failed to get event",ok);
+ if (event.clazz == DFEC_WINDOW) {
+ switch (event.window.type) {
+ case DWET_BUTTONDOWN:
+ case DWET_BUTTONUP:
+ case DWET_MOTION:
+ handleMouseEvents(event);
+ break;
+ case DWET_WHEEL:
+ handleWheelEvent(event);
+ break;
+ case DWET_KEYDOWN:
+ case DWET_KEYUP:
+ handleKeyEvents(event);
+ break;
+ case DWET_ENTER:
+ case DWET_LEAVE:
+ handleEnterLeaveEvents(event);
+ default:
+ break;
+ }
+
+ }
+
+ hasEvent = m_eventBuffer->HasEvent(m_eventBuffer);
+ }
+}
+
+void QDirectFbInput::handleMouseEvents(const DFBEvent &event)
+{
+ QPoint p(event.window.x, event.window.y);
+ QPoint globalPos = globalPoint(event);
+ Qt::MouseButtons buttons = QDirectFbConvenience::mouseButtons(event.window.buttons);
+
+ IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
+ IDirectFBWindow *window;
+ layer->GetWindow(layer,event.window.window_id,&window);
+
+ long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
+
+ if (event.window.type == DWET_BUTTONDOWN) {
+ window->GrabPointer(window);
+ } else if (event.window.type == DWET_BUTTONUP) {
+ window->UngrabPointer(window);
+ }
+ QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindowSystemInterface::handleMouseEvent(tlw, timestamp, p, globalPos, buttons);
+}
+
+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);
+ QWindowSystemInterface::handleWheelEvent(tlw, timestamp, p, globalPos,
+ event.window.step*120,
+ Qt::Vertical);
+}
+
+void QDirectFbInput::handleKeyEvents(const DFBEvent &event)
+{
+ QEvent::Type type = QDirectFbConvenience::eventType(event.window.type);
+ Qt::Key key = QDirectFbConvenience::keyMap()->value(event.window.key_symbol);
+ Qt::KeyboardModifiers modifiers = QDirectFbConvenience::keyboardModifiers(event.window.modifiers);
+
+ long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
+
+ 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);
+ QWindowSystemInterface::handleKeyEvent(tlw, timestamp, type, key, modifiers, character);
+}
+
+void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event)
+{
+ QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ switch (event.window.type) {
+ case DWET_ENTER:
+ QWindowSystemInterface::handleEnterEvent(tlw);
+ break;
+ case DWET_LEAVE:
+ QWindowSystemInterface::handleLeaveEvent(tlw);
+ break;
+ default:
+ break;
+ }
+}
+
+inline QPoint QDirectFbInput::globalPoint(const DFBEvent &event) const
+{
+ IDirectFBWindow *window;
+ m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,event.window.window_id,&window);
+ int x,y;
+ window->GetPosition(window,&x,&y);
+ return QPoint(event.window.cx +x, event.window.cy + y);
+}
+
diff --git a/src/plugins/platforms/directfb/qdirectfbinput.h b/src/plugins/platforms/directfb/qdirectfbinput.h
new file mode 100644
index 0000000000..35a345c07b
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbinput.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$
+** 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 QDIRECTFBINPUT_H
+#define QDIRECTFBINPUT_H
+
+#include <QSemaphore>
+#include <QObject>
+#include <QHash>
+#include <QPoint>
+#include <QEvent>
+
+#include <QtGui/qwindowdefs.h>
+
+#include <directfb.h>
+
+class QDirectFbInput : public QObject
+{
+ Q_OBJECT
+public:
+ QDirectFbInput(QObject *parent);
+ void addWindow(DFBWindowID id, QWidget *tlw);
+ void removeWindow(WId wId);
+
+public slots:
+ void runInputEventLoop();
+ void stopInputEventLoop();
+ void handleEvents();
+
+private:
+ void handleMouseEvents(const DFBEvent &event);
+ void handleWheelEvent(const DFBEvent &event);
+ void handleKeyEvents(const DFBEvent &event);
+ void handleEnterLeaveEvents(const DFBEvent &event);
+ inline QPoint globalPoint(const DFBEvent &event) const;
+
+
+ IDirectFB *m_dfbInterface;
+ IDirectFBDisplayLayer *m_dfbDisplayLayer;
+ IDirectFBEventBuffer *m_eventBuffer;
+
+ bool m_shouldStop;
+ QSemaphore m_waitStop;
+
+ QHash<DFBWindowID,QWidget *>m_tlwMap;
+};
+
+#endif // QDIRECTFBINPUT_H
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
new file mode 100644
index 0000000000..52b7774548
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** 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 "qdirectfbintegration.h"
+#include "qdirectfbwindowsurface.h"
+#include "qdirectfbblitter.h"
+#include "qdirectfbconvenience.h"
+#include "qdirectfbcursor.h"
+#include "qdirectfbwindow.h"
+
+#include "qgenericunixfontdatabase.h"
+
+#include <private/qwindowsurface_raster_p.h>
+#include <private/qpixmap_raster_p.h>
+
+#include <QtGui/private/qpixmap_blitter_p.h>
+#include <QtGui/private/qpixmapdata_p.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QThread>
+
+QT_BEGIN_NAMESPACE
+
+QDirectFbScreen::QDirectFbScreen(int display)
+ :QPlatformScreen()
+{
+ m_layer = QDirectFbConvenience::dfbDisplayLayer(display);
+ m_layer->SetCooperativeLevel(m_layer,DLSCL_SHARED);
+
+ DFBDisplayLayerConfig config;
+ m_layer->GetConfiguration(m_layer, &config);
+
+ m_format = QDirectFbConvenience::imageFormatFromSurfaceFormat(config.pixelformat, config.surface_caps);
+ m_geometry = QRect(0,0,config.width,config.height);
+ const int dpi = 72;
+ const qreal inch = 25.4;
+ m_depth = QDirectFbConvenience::colorDepthForSurface(config.pixelformat);
+ m_physicalSize = QSize(qRound(config.width * inch / dpi), qRound(config.height *inch / dpi));
+
+ cursor = new QDirectFBCursor(this);
+}
+
+QDirectFbScreen::~QDirectFbScreen()
+{
+}
+
+QDirectFbIntegration::QDirectFbIntegration()
+ : mFontDb(new QGenericUnixFontDatabase())
+{
+ 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());
+
+ DFBResult result = DirectFBInit(&argc, &argv);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen: error initializing DirectFB",
+ result);
+ }
+ delete[] argv;
+
+
+ QDirectFbScreen *primaryScreen = new QDirectFbScreen(0);
+ mScreens.append(primaryScreen);
+
+ mInputRunner = new QThread;
+ mInput = new QDirectFbInput(0);
+ mInput->moveToThread(mInputRunner);
+ QObject::connect(mInputRunner,SIGNAL(started()),mInput,SLOT(runInputEventLoop()));
+ mInputRunner->start();
+}
+
+QDirectFbIntegration::~QDirectFbIntegration()
+{
+ mInput->stopInputEventLoop();
+ delete mInputRunner;
+ delete mInput;
+}
+
+QPixmapData *QDirectFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ if (type == QPixmapData::BitmapType)
+ return new QRasterPixmapData(type);
+ else
+ return new QDirectFbBlitterPixmapData;
+}
+
+QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ QDirectFbInput *input = const_cast<QDirectFbInput *>(mInput);//gah
+ return new QDirectFbWindow(widget,input);
+}
+
+QWindowSurface *QDirectFbIntegration::createWindowSurface(QWidget *widget, WId winId) const
+{
+ return new QDirectFbWindowSurface(widget,winId);
+}
+
+QPlatformFontDatabase *QDirectFbIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h
new file mode 100644
index 0000000000..bfd4af4230
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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 QPLATFORMINTEGRATION_DIRECTFB_H
+#define QPLATFORMINTEGRATION_DIRECTFB_H
+
+#include "qdirectfbinput.h"
+
+#include <QtGui/QPlatformIntegration>
+#include <directfb.h>
+#include <directfb_version.h>
+
+QT_BEGIN_NAMESPACE
+
+class QThread;
+class QDirectFBCursor;
+
+class QDirectFbScreen : public QPlatformScreen
+{
+Q_OBJECT
+public:
+ QDirectFbScreen(int display);
+ ~QDirectFbScreen();
+
+ QRect geometry() const { return m_geometry; }
+ int depth() const { return m_depth; }
+ QImage::Format format() const { return m_format; }
+ QSize physicalSize() const { return m_physicalSize; }
+
+public:
+ QRect m_geometry;
+ int m_depth;
+ QImage::Format m_format;
+ QSize m_physicalSize;
+
+ IDirectFBDisplayLayer *m_layer;
+
+private:
+ QDirectFBCursor * cursor;
+
+};
+
+class QDirectFbIntegration : public QPlatformIntegration
+{
+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; }
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+private:
+ QList<QPlatformScreen *> mScreens;
+ QDirectFbInput *mInput;
+ QThread *mInputRunner;
+ QPlatformFontDatabase *mFontDb;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.cpp b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
new file mode 100644
index 0000000000..040580b630
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** 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 "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)
+{
+ IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
+ DFBDisplayLayerConfig layerConfig;
+ layer->GetConfiguration(layer,&layerConfig);
+
+ DFBWindowDescription description;
+ memset(&description,0,sizeof(DFBWindowDescription));
+ description.flags = DFBWindowDescriptionFlags(DWDESC_WIDTH|DWDESC_HEIGHT|DWDESC_POSX|DWDESC_POSY|DWDESC_SURFACE_CAPS
+#if DIRECTFB_MINOR_VERSION >= 1
+ |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();
+
+ if (layerConfig.surface_caps & DSCAPS_PREMULTIPLIED)
+ description.surface_caps = DSCAPS_PREMULTIPLIED;
+ description.pixelformat = layerConfig.pixelformat;
+
+#if DIRECTFB_MINOR_VERSION >= 1
+ description.options = DFBWindowOptions(DWOP_ALPHACHANNEL);
+#endif
+ description.caps = DFBWindowCapabilities(DWCAPS_DOUBLEBUFFER|DWCAPS_ALPHACHANNEL);
+ description.surface_caps = DSCAPS_PREMULTIPLIED;
+
+ DFBResult result = layer->CreateWindow(layer,&description,&m_dfbWindow);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFbGraphicsSystemScreen: failed to create window",result);
+ }
+
+ m_dfbWindow->SetOpacity(m_dfbWindow,0xff);
+
+ setVisible(widget()->isVisible());
+
+ DFBWindowID id;
+ m_dfbWindow->GetID(m_dfbWindow, &id);
+ m_inputHandler->addWindow(id,tlw);
+}
+
+QDirectFbWindow::~QDirectFbWindow()
+{
+ m_inputHandler->removeWindow(winId());
+ m_dfbWindow->Destroy(m_dfbWindow);
+}
+
+void QDirectFbWindow::setGeometry(const QRect &rect)
+{
+ bool isMoveOnly = (rect.topLeft() != geometry().topLeft()) && (rect.size() == geometry().size());
+ QPlatformWindow::setGeometry(rect);
+ if (widget()->isVisible() && !(widget()->testAttribute(Qt::WA_DontShowOnScreen))) {
+ m_dfbWindow->SetBounds(m_dfbWindow, rect.x(),rect.y(),
+ rect.width(), rect.height());
+
+ //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();
+ }
+ }
+}
+
+void QDirectFbWindow::setOpacity(qreal level)
+{
+ const quint8 windowOpacity = quint8(level * 0xff);
+ m_dfbWindow->SetOpacity(m_dfbWindow,windowOpacity);
+}
+
+void QDirectFbWindow::setVisible(bool visible)
+{
+ if (visible) {
+ int x = geometry().x();
+ int y = geometry().y();
+ m_dfbWindow->MoveTo(m_dfbWindow,x,y);
+ } else {
+ IDirectFBDisplayLayer *displayLayer;
+ QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),DLID_PRIMARY,&displayLayer);
+
+ DFBDisplayLayerConfig config;
+ displayLayer->GetConfiguration(displayLayer,&config);
+ m_dfbWindow->MoveTo(m_dfbWindow,config.width+1,config.height + 1);
+ }
+}
+
+Qt::WindowFlags QDirectFbWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ switch (flags & Qt::WindowType_Mask) {
+ case Qt::ToolTip: {
+ DFBWindowOptions options;
+ m_dfbWindow->GetOptions(m_dfbWindow,&options);
+ options = DFBWindowOptions(options | DWOP_GHOST);
+ m_dfbWindow->SetOptions(m_dfbWindow,options);
+ break; }
+ default:
+ break;
+ }
+
+ m_dfbWindow->SetStackingClass(m_dfbWindow, flags & Qt::WindowStaysOnTopHint ? DWSC_UPPER : DWSC_MIDDLE);
+ return flags;
+}
+
+void QDirectFbWindow::raise()
+{
+ m_dfbWindow->RaiseToTop(m_dfbWindow);
+}
+
+void QDirectFbWindow::lower()
+{
+ m_dfbWindow->LowerToBottom(m_dfbWindow);
+}
+
+WId QDirectFbWindow::winId() const
+{
+ DFBWindowID id;
+ 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
new file mode 100644
index 0000000000..4c6476a2b3
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 QDIRECTFBWINDOW_H
+#define QDIRECTFBWINDOW_H
+
+#include <QPlatformWindow>
+
+#include "qdirectfbconvenience.h"
+#include "qdirectfbinput.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDirectFbWindow : public QPlatformWindow
+{
+public:
+ QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler);
+ ~QDirectFbWindow();
+
+ void setGeometry(const QRect &rect);
+ void setOpacity(qreal level);
+
+ void setVisible(bool visible);
+
+ Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ void raise();
+ void lower();
+ WId winId() const;
+
+ QPlatformGLContext *glContext() const;
+
+private:
+ IDirectFBWindow *m_dfbWindow;
+ QDirectFbInput *m_inputHandler;
+
+ QPlatformGLContext *m_context;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDIRECTFBWINDOW_H
diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp b/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp
new file mode 100644
index 0000000000..81f989da5d
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.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$
+** 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 "qdirectfbwindowsurface.h"
+#include "qdirectfbintegration.h"
+#include "qdirectfbblitter.h"
+#include "qdirectfbconvenience.h"
+#include <private/qpixmap_blitter_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+QDirectFbWindowSurface::QDirectFbWindowSurface(QWidget *window, WId wId)
+ : QWindowSurface(window), m_pixmap(0), m_pmdata(0), m_dfbSurface(0)
+{
+
+ IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
+
+ DFBWindowID id(wId);
+ 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;
+ m_pmdata->setBlittable(blitter);
+ m_pixmap = new QPixmap(m_pmdata);
+}
+
+QDirectFbWindowSurface::~QDirectFbWindowSurface()
+{
+ delete m_pixmap;
+}
+
+QPaintDevice *QDirectFbWindowSurface::paintDevice()
+{
+ return m_pixmap;
+}
+
+void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ m_pmdata->blittable()->unlock();
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0 ; i < rects.size(); i++) {
+ const QRect rect = rects.at(i);
+ DFBRegion dfbReg = { rect.x() + offset.x(),rect.y() + offset.y(),rect.right() + offset.x(),rect.bottom() + offset.y()};
+ m_dfbSurface->Flip(m_dfbSurface, &dfbReg, DFBSurfaceFlipFlags(DSFLIP_BLIT|DSFLIP_ONSYNC));
+ }
+}
+
+void QDirectFbWindowSurface::resize(const QSize &size)
+{
+ QWindowSurface::resize(size);
+
+ //Have to add 1 ref ass it will be removed by deleting the old blitter in setBlittable
+ m_dfbSurface->AddRef(m_dfbSurface);
+ QDirectFbBlitter *blitter = new QDirectFbBlitter(size,m_dfbSurface);
+ m_pmdata->setBlittable(blitter);
+}
+
+static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy)
+{
+ const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
+ surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy);
+ const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy };
+ surface->Flip(surface, &region, DFBSurfaceFlipFlags(DSFLIP_BLIT));
+}
+
+bool QDirectFbWindowSurface::scroll(const QRegion &area, int dx, int dy)
+{
+ m_pmdata->blittable()->unlock();
+
+ if (!m_dfbSurface || area.isEmpty())
+ return false;
+ m_dfbSurface->SetBlittingFlags(m_dfbSurface, DSBLIT_NOFX);
+ if (area.rectCount() == 1) {
+ scrollSurface(m_dfbSurface, area.boundingRect(), dx, dy);
+ } else {
+ const QVector<QRect> rects = area.rects();
+ const int n = rects.size();
+ for (int i=0; i<n; ++i) {
+ scrollSurface(m_dfbSurface, rects.at(i), dx, dy);
+ }
+ }
+ return true;
+}
+
+void QDirectFbWindowSurface::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+}
+
+void QDirectFbWindowSurface::endPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.h b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
new file mode 100644
index 0000000000..a762bf6241
--- /dev/null
+++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 QWINDOWSURFACE_DIRECTFB_H
+#define QWINDOWSURFACE_DIRECTFB_H
+
+#include <QtGui/private/qwindowsurface_p.h>
+#include <private/qpixmap_blitter_p.h>
+
+#include <directfb.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDirectFbWindowSurface : public QWindowSurface
+{
+public:
+ QDirectFbWindowSurface(QWidget *window, WId wid);
+ ~QDirectFbWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize (const QSize &size);
+ bool scroll(const QRegion &area, int dx, int dy);
+
+ void beginPaint(const QRegion &region);
+ void endPaint(const QRegion &region);
+
+private:
+ void lockSurfaceToImage();
+
+ QPixmap *m_pixmap;
+ QBlittablePixmapData *m_pmdata;
+
+ IDirectFBSurface *m_dfbSurface;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/eglconvenience/eglconvenience.pri b/src/plugins/platforms/eglconvenience/eglconvenience.pri
new file mode 100644
index 0000000000..322d4e4633
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/eglconvenience.pri
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..df7abc1401
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
@@ -0,0 +1,324 @@
+/****************************************************************************
+**
+** 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 "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
new file mode 100644
index 0000000000..c7d3d61ae5
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/qeglconvenience.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 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
new file mode 100644
index 0000000000..ae5215f320
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** 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 "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/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
new file mode 100644
index 0000000000..69835d7eb4
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.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$
+** 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 QOPENKODEGLINTEGRATION_H
+#define QOPENKODEGLINTEGRATION_H
+
+#include <QtGui/QPlatformGLContext>
+#include <EGL/egl.h>
+
+class QEGLPlatformContext : public QPlatformGLContext
+{
+public:
+ QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi);
+ ~QEGLPlatformContext();
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ EGLContext eglContext() const;
+private:
+ EGLContext m_eglContext;
+ EGLDisplay m_eglDisplay;
+ EGLSurface m_eglSurface;
+ EGLenum m_eglApi;
+
+ QPlatformWindowFormat m_windowFormat;
+};
+
+#endif //QOPENKODEGLINTEGRATION_H
diff --git a/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp b/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
new file mode 100644
index 0000000000..45746e99a7
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** 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 "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/qxlibeglintegration.h b/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
new file mode 100644
index 0000000000..6c2e266cbc
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** 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 QTESTLITEEGLINTEGRATION_H
+#define QTESTLITEEGLINTEGRATION_H
+
+#include "qeglconvenience.h"
+
+class QXlibEglIntegration
+{
+public:
+ static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config);
+};
+
+#endif // QTESTLITEEGLINTEGRATION_H
diff --git a/src/plugins/platforms/eglconvenience/xlibeglintegration.pri b/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
new file mode 100644
index 0000000000..9404a70373
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..7ad8fd985b
--- /dev/null
+++ b/src/plugins/platforms/eglfs/eglfs.pro
@@ -0,0 +1,31 @@
+TARGET = qeglfs
+TEMPLATE = lib
+CONFIG += plugin
+
+QT += opengl
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+#DEFINES += QEGL_EXTRA_DEBUG
+
+#DEFINES += Q_OPENKODE
+
+SOURCES = main.cpp \
+ qeglfsintegration.cpp \
+ ../eglconvenience/qeglconvenience.cpp \
+ ../eglconvenience/qeglplatformcontext.cpp \
+ qeglfswindow.cpp \
+ qeglfswindowsurface.cpp \
+ qeglfsscreen.cpp
+
+HEADERS = qeglfsintegration.h \
+ ../eglconvenience/qeglconvenience.h \
+ ../eglconvenience/qeglplatformcontext.h \
+ qeglfswindow.h \
+ qeglfswindowsurface.h \
+ qeglfsscreen.h
+
+include(../fontdatabases/genericunix/genericunix.pri)
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/eglfs/main.cpp b/src/plugins/platforms/eglfs/main.cpp
new file mode 100644
index 0000000000..c07e54673c
--- /dev/null
+++ b/src/plugins/platforms/eglfs/main.cpp
@@ -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$
+** 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 <QtGui/QPlatformIntegrationPlugin>
+#include "qeglfsintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEglIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QEglIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "EglFS";
+ return list;
+}
+
+QPlatformIntegration* QEglIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "eglfs")
+ return new QEglFSIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(eglintegration, QEglIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
new file mode 100644
index 0000000000..1bc0806e7e
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** 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 "qeglfsintegration.h"
+
+#include "qeglfswindow.h"
+#include "qeglfswindowsurface.h"
+
+#include "qgenericunixfontdatabase.h"
+
+#include <QtGui/QPlatformWindow>
+#include <QtGui/QPlatformWindowFormat>
+#include <QtOpenGL/private/qpixmapdata_gl_p.h>
+
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+QEglFSIntegration::QEglFSIntegration()
+ : mFontDb(new QGenericUnixFontDatabase())
+{
+ m_primaryScreen = new QEglFSScreen(EGL_DEFAULT_DISPLAY);
+
+ mScreens.append(m_primaryScreen);
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglIntegration\n");
+#endif
+}
+
+bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPixmapData *QEglFSIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglIntegration::createPixmapData %d\n", type);
+#endif
+ return new QGLPixmapData(type);
+}
+
+QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglIntegration::createPlatformWindow %p\n",widget);
+#endif
+ return new QEglFSWindow(widget, m_primaryScreen);
+}
+
+
+QWindowSurface *QEglFSIntegration::createWindowSurface(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglIntegration::createWindowSurface %p\n",widget);
+#endif
+ return new QEglFSWindowSurface(m_primaryScreen,widget);
+}
+
+QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
new file mode 100644
index 0000000000..65b834f371
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 EGLINTEGRATION_H
+#define EGLINTEGRATION_H
+
+#include "qeglfsscreen.h"
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSIntegration : public QPlatformIntegration
+{
+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; }
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+private:
+ QPlatformFontDatabase *mFontDb;
+ QList<QPlatformScreen *> mScreens;
+ QEglFSScreen *m_primaryScreen;
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
new file mode 100644
index 0000000000..b6f2805ee0
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** 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 "qeglfsscreen.h"
+
+#include "../eglconvenience/qeglconvenience.h"
+#include "../eglconvenience/qeglplatformcontext.h"
+
+#ifdef Q_OPENKODE
+#include <KD/kd.h>
+#include <KD/NV_initialize.h>
+#endif //Q_OPENKODE
+
+QT_BEGIN_NAMESPACE
+
+// #define QEGL_EXTRA_DEBUG
+
+#ifdef QEGL_EXTRA_DEBUG
+struct AttrInfo { EGLint attr; const char *name; };
+static struct AttrInfo attrs[] = {
+ {EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE"},
+ {EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE"},
+ {EGL_BLUE_SIZE, "EGL_BLUE_SIZE"},
+ {EGL_GREEN_SIZE, "EGL_GREEN_SIZE"},
+ {EGL_RED_SIZE, "EGL_RED_SIZE"},
+ {EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE"},
+ {EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE"},
+ {EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT"},
+ {EGL_CONFIG_ID, "EGL_CONFIG_ID"},
+ {EGL_LEVEL, "EGL_LEVEL"},
+ {EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT"},
+ {EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS"},
+ {EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH"},
+ {EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE"},
+ {EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID"},
+ {EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE"},
+ {EGL_SAMPLES, "EGL_SAMPLES"},
+ {EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS"},
+ {EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE"},
+ {EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE"},
+ {EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE"},
+ {EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE"},
+ {EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE"},
+ {EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB"},
+ {EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA"},
+ {EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL"},
+ {EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL"},
+ {-1, 0}};
+#endif //QEGL_EXTRA_DEBUG
+
+QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display)
+ : m_depth(32)
+ , m_format(QImage::Format_Invalid)
+ , m_platformContext(0)
+ , m_surface(0)
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglScreen %p\n", this);
+#endif
+
+ EGLint major, minor;
+#ifdef QEGL_EXTRA_DEBUG
+ EGLint index;
+#endif
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ qWarning("Could not bind GL_ES API\n");
+ qFatal("EGL error");
+ }
+
+ m_dpy = eglGetDisplay(display);
+ if (m_dpy == EGL_NO_DISPLAY) {
+ qWarning("Could not open egl display\n");
+ qFatal("EGL error");
+ }
+ qWarning("Opened display %p\n", m_dpy);
+
+ if (!eglInitialize(m_dpy, &major, &minor)) {
+ qWarning("Could not initialize egl display\n");
+ qFatal("EGL error");
+ }
+
+ qWarning("Initialized display %d %d\n", major, minor);
+
+ int swapInterval = 1;
+ QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
+ if (!swapIntervalString.isEmpty()) {
+ bool ok;
+ swapInterval = swapIntervalString.toInt(&ok);
+ if (!ok)
+ swapInterval = 1;
+ }
+ eglSwapInterval(m_dpy, swapInterval);
+}
+
+void QEglFSScreen::createAndSetPlatformContext() const {
+ const_cast<QEglFSScreen *>(this)->createAndSetPlatformContext();
+}
+
+void QEglFSScreen::createAndSetPlatformContext()
+{
+ QPlatformWindowFormat platformFormat = QPlatformWindowFormat::defaultFormat();
+
+ platformFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
+
+ QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH");
+ if (depthString.toInt() == 16) {
+ platformFormat.setDepth(16);
+ platformFormat.setRedBufferSize(5);
+ platformFormat.setGreenBufferSize(6);
+ platformFormat.setBlueBufferSize(5);
+ m_depth = 16;
+ m_format = QImage::Format_RGB16;
+ } else {
+ platformFormat.setDepth(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);
+ }
+
+
+ EGLConfig config = q_configFromQPlatformWindowFormat(m_dpy, platformFormat);
+
+ EGLNativeWindowType eglWindow = 0;
+#ifdef Q_OPENKODE
+ if (kdInitializeNV() == KD_ENOTINITIALIZED) {
+ qFatal("Did not manage to initialize openkode");
+ }
+ KDWindow *window = kdCreateWindow(m_dpy,config,0);
+
+ kdRealizeWindow(window,&eglWindow);
+#endif
+
+ m_surface = eglCreateWindowSurface(m_dpy, config, eglWindow, NULL);
+ if (m_surface == EGL_NO_SURFACE) {
+ qWarning("Could not create the egl surface: error = 0x%x\n", eglGetError());
+ eglTerminate(m_dpy);
+ qFatal("EGL error");
+ }
+ // qWarning("Created surface %dx%d\n", w, h);
+
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("Configuration %d matches requirements\n", (int)config);
+
+ for (index = 0; attrs[index].attr != -1; ++index) {
+ EGLint value;
+ if (eglGetConfigAttrib(m_dpy, config, attrs[index].attr, &value)) {
+ qWarning("\t%s: %d\n", attrs[index].name, (int)value);
+ }
+ }
+ 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);
+ m_platformContext = platformContext;
+
+ EGLint w,h; // screen size detection
+ eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w);
+ eglQuerySurface(m_dpy, m_surface, EGL_HEIGHT, &h);
+
+ m_geometry = QRect(0,0,w,h);
+
+}
+
+QRect QEglFSScreen::geometry() const
+{
+ if (m_geometry.isNull()) {
+ createAndSetPlatformContext();
+ }
+ return m_geometry;
+}
+
+int QEglFSScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QEglFSScreen::format() const
+{
+ if (m_format == QImage::Format_Invalid)
+ createAndSetPlatformContext();
+ return m_format;
+}
+QPlatformGLContext *QEglFSScreen::platformContext() const
+{
+ if (!m_platformContext) {
+ QEglFSScreen *that = const_cast<QEglFSScreen *>(this);
+ that->createAndSetPlatformContext();
+ }
+ return m_platformContext;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
new file mode 100644
index 0000000000..f300842307
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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 QEGLSCREEN_H
+#define QEGLSCREEN_H
+
+#include <QPlatformScreen>
+
+#include <QtCore/QTextStream>
+
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformGLContext;
+
+class QEglFSScreen : public QPlatformScreen //huh: FullScreenScreen ;) just to follow namespace
+{
+public:
+ QEglFSScreen(EGLNativeDisplayType display);
+ ~QEglFSScreen() {}
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+
+ QPlatformGLContext *platformContext() const;
+
+private:
+ void createAndSetPlatformContext() const;
+ void createAndSetPlatformContext();
+
+ QRect m_geometry;
+ int m_depth;
+ QImage::Format m_format;
+ QPlatformGLContext *m_platformContext;
+ EGLDisplay m_dpy;
+ EGLSurface m_surface;
+};
+
+QT_END_NAMESPACE
+#endif // QEGLSCREEN_H
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
new file mode 100644
index 0000000000..2ef12aa77d
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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 "qeglfswindow.h"
+
+#include <QtGui/QWindowSystemInterface>
+
+QT_BEGIN_NAMESPACE
+
+QEglFSWindow::QEglFSWindow(QWidget *w, QEglFSScreen *screen)
+ : QPlatformWindow(w), m_screen(screen)
+{
+ 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));
+#endif
+}
+
+
+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);
+
+ QPlatformWindow::setGeometry(rect);
+}
+
+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
new file mode 100644
index 0000000000..f125eab3c1
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfswindow.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 QEGLWINDOW_H
+#define QEGLWINDOW_H
+
+#include "qeglfsintegration.h"
+#include "qeglfsscreen.h"
+
+#include <QPlatformWindow>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSWindow : public QPlatformWindow
+{
+public:
+ QEglFSWindow(QWidget *w, QEglFSScreen *screen);
+
+ void setGeometry(const QRect &);
+ WId winId() const;
+
+ QPlatformGLContext *glContext() const;
+
+private:
+ QEglFSScreen *m_screen;
+ WId m_winid;
+};
+QT_END_NAMESPACE
+#endif // QEGLWINDOW_H
diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
new file mode 100644
index 0000000000..393e646d7b
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 "qeglfswindowsurface.h"
+
+#include <QtGui/QPlatformGLContext>
+
+#include <QtOpenGL/private/qgl_p.h>
+#include <QtOpenGL/private/qglpaintdevice_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSPaintDevice : public QGLPaintDevice
+{
+public:
+ QEglFSPaintDevice(QEglFSScreen *screen, QWidget *widget)
+ :QGLPaintDevice(), m_screen(screen)
+ {
+ #ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglPaintDevice %p, %p, %p",this, screen, widget);
+ #endif
+ }
+
+ QSize size() const { return m_screen->geometry().size(); }
+ QGLContext* context() const { return QGLContext::fromPlatformGLContext(m_screen->platformContext());}
+
+ QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
+
+ void beginPaint(){
+ QGLPaintDevice::beginPaint();
+ }
+private:
+ QEglFSScreen *m_screen;
+ QGLContext *m_context;
+};
+
+
+QEglFSWindowSurface::QEglFSWindowSurface( QEglFSScreen *screen, QWidget *window )
+ :QWindowSurface(window)
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglWindowSurface %p, %p", window, screen);
+#endif
+ m_paintDevice = new QEglFSPaintDevice(screen,window);
+}
+
+void QEglFSWindowSurface::flush(QWidget *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);
+#endif
+ widget->platformWindow()->glContext()->swapBuffers();
+}
+
+void QEglFSWindowSurface::resize(const QSize &size)
+{
+ Q_UNUSED(size);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.h b/src/plugins/platforms/eglfs/qeglfswindowsurface.h
new file mode 100644
index 0000000000..2fa655b01f
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfswindowsurface.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 QEGLWINDOWSURFACE_H
+#define QEGLWINDOWSURFACE_H
+
+#include "qeglfsintegration.h"
+#include "qeglfswindow.h"
+
+#include <QtGui/private/qwindowsurface_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSWindowSurface : public QWindowSurface
+{
+public:
+ QEglFSWindowSurface(QEglFSScreen *screen, QWidget *window);
+ ~QEglFSWindowSurface() {}
+
+ QPaintDevice *paintDevice() { return m_paintDevice; }
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size);
+private:
+ QPaintDevice *m_paintDevice;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLWINDOWSURFACE_H
diff --git a/src/plugins/platforms/externalplugin.pri b/src/plugins/platforms/externalplugin.pri
new file mode 100644
index 0000000000..54da4d957c
--- /dev/null
+++ b/src/plugins/platforms/externalplugin.pri
@@ -0,0 +1,29 @@
+#
+# 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)
+
+include($$QT_SOURCE_TREE/src/plugins/qpluginbase.pri)
diff --git a/src/plugins/platforms/fb_base/fb_base.cpp b/src/plugins/platforms/fb_base/fb_base.cpp
new file mode 100644
index 0000000000..e118ce856c
--- /dev/null
+++ b/src/plugins/platforms/fb_base/fb_base.cpp
@@ -0,0 +1,507 @@
+/****************************************************************************
+**
+** 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 "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
new file mode 100644
index 0000000000..c5ae378723
--- /dev/null
+++ b/src/plugins/platforms/fb_base/fb_base.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** 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 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
new file mode 100644
index 0000000000..41bd87fbca
--- /dev/null
+++ b/src/plugins/platforms/fb_base/fb_base.pri
@@ -0,0 +1,2 @@
+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
new file mode 100644
index 0000000000..e08c0c5571
--- /dev/null
+++ b/src/plugins/platforms/fb_base/fb_base.pro
@@ -0,0 +1,23 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2009-11-05T13:22:31
+#
+#-------------------------------------------------
+
+#QT -= core gui
+TARGET = fb_base
+#include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/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
new file mode 100644
index 0000000000..da4698df0d
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri
@@ -0,0 +1,86 @@
+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
+
+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
new file mode 100644
index 0000000000..895f8af58e
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** 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 "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 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);
+ }
+
+ 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
new file mode 100644
index 0000000000..f04d453751
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 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 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
new file mode 100644
index 0000000000..19c74ed089
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 0000000000..2a3fd5a8b5
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -0,0 +1,601 @@
+/****************************************************************************
+**
+** 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 "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;
+
+ //try and get the pattern
+ FcPattern *pattern = FcPatternCreate();
+
+ bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+
+ engine = new QFontEngineFT(fontDef);
+
+ 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);
+
+ QFontEngineFT::HintStyle default_hint_style;
+
+ if (FcConfigSubstitute(0,pattern,FcMatchPattern)) {
+
+ //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);
+ 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);
+ FcConfigSubstitute(0, pattern, FcMatchFont);
+
+ FcResult result = FcResultMatch;
+ FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
+
+ if (fontSet && 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)) {
+ fallbackFamilies << familyName;
+ }
+
+ }
+ }
+// qDebug() << "fallbackFamilies for:" << family << fallbackFamilies;
+
+ return fallbackFamilies;
+}
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
new file mode 100644
index 0000000000..ee441f7a1a
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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 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
new file mode 100644
index 0000000000..1153ab36b7
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
@@ -0,0 +1,10 @@
+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/fontdatabases/genericunix/qgenericunixfontdatabase.h b/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
new file mode 100644
index 0000000000..bfe014acf2
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** 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 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
diff --git a/src/plugins/platforms/glxconvenience/glxconvenience.pri b/src/plugins/platforms/glxconvenience/glxconvenience.pri
new file mode 100644
index 0000000000..d6c992229e
--- /dev/null
+++ b/src/plugins/platforms/glxconvenience/glxconvenience.pri
@@ -0,0 +1,7 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qglxconvenience.h
+
+SOURCES += \
+ $$PWD/qglxconvenience.cpp
diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
new file mode 100644
index 0000000000..7cee3e2ea1
--- /dev/null
+++ b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** 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 "qglxconvenience.h"
+
+#include <QtCore/QVector>
+
+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();
+ }
+
+ 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)
+ break;
+ } 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
new file mode 100644
index 0000000000..2c59dbb324
--- /dev/null
+++ b/src/plugins/platforms/glxconvenience/qglxconvenience.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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 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/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro
new file mode 100644
index 0000000000..216b899fdb
--- /dev/null
+++ b/src/plugins/platforms/linuxfb/linuxfb.pro
@@ -0,0 +1,13 @@
+TARGET = qlinuxfbgraphicssystem
+include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+SOURCES = main.cpp qlinuxfbintegration.cpp
+HEADERS = qlinuxfbintegration.h
+
+include(../fb_base/fb_base.pri)
+include(../fontdatabases/genericunix/genericunix.pri)
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/linuxfb/main.cpp b/src/plugins/platforms/linuxfb/main.cpp
new file mode 100644
index 0000000000..fb14ef4d13
--- /dev/null
+++ b/src/plugins/platforms/linuxfb/main.cpp
@@ -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$
+** 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 <QPlatformIntegrationPlugin>
+#include "qlinuxfbintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLinuxFbIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QLinuxFbIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "LinuxFb";
+ return list;
+}
+
+QPlatformIntegration* QLinuxFbIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "linuxfb")
+ return new QLinuxFbIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(linuxfb, QLinuxFbIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
new file mode 100644
index 0000000000..a088a31d6d
--- /dev/null
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -0,0 +1,875 @@
+/****************************************************************************
+**
+** 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 "qlinuxfbintegration.h"
+#include "../fb_base/fb_base.h"
+#include "qgenericunixfontdatabase.h"
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <private/qcore_unix_p.h> // overrides QT_OPEN
+#include <qimage.h>
+#include <qdebug.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/kd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <limits.h>
+#include <signal.h>
+
+#if !defined(Q_OS_DARWIN) && !defined(Q_OS_FREEBSD)
+#include <linux/fb.h>
+
+#ifdef __i386__
+#include <asm/mtrr.h>
+#endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QLinuxFbIntegrationPrivate
+{
+public:
+ QLinuxFbIntegrationPrivate();
+ ~QLinuxFbIntegrationPrivate();
+
+ void openTty();
+ void closeTty();
+
+ int fd;
+ int startupw;
+ int startuph;
+ int startupd;
+ bool blank;
+
+ bool doGraphicsMode;
+#ifdef QT_QWS_DEPTH_GENERIC
+ bool doGenericColors;
+#endif
+ int ttyfd;
+ long oldKdMode;
+ QString ttyDevice;
+ QString displaySpec;
+};
+
+QLinuxFbIntegrationPrivate::QLinuxFbIntegrationPrivate()
+ : fd(-1), blank(true), doGraphicsMode(true),
+#ifdef QT_QWS_DEPTH_GENERIC
+ doGenericColors(false),
+#endif
+ ttyfd(-1), oldKdMode(KD_TEXT)
+{
+}
+
+QLinuxFbIntegrationPrivate::~QLinuxFbIntegrationPrivate()
+{
+ closeTty();
+}
+
+void QLinuxFbIntegrationPrivate::openTty()
+{
+ const char *const devs[] = {"/dev/tty0", "/dev/tty", "/dev/console", 0};
+
+ if (ttyDevice.isEmpty()) {
+ for (const char * const *dev = devs; *dev; ++dev) {
+ ttyfd = QT_OPEN(*dev, O_RDWR);
+ if (ttyfd != -1)
+ break;
+ }
+ } else {
+ ttyfd = QT_OPEN(ttyDevice.toAscii().constData(), O_RDWR);
+ }
+
+ if (ttyfd == -1)
+ return;
+
+ 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";
+ QT_WRITE(ttyfd, termctl, sizeof(termctl));
+}
+
+void QLinuxFbIntegrationPrivate::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";
+ QT_WRITE(ttyfd, termctl, sizeof(termctl));
+
+ QT_CLOSE(ttyfd);
+ ttyfd = -1;
+}
+
+QLinuxFbIntegration::QLinuxFbIntegration()
+ :fontDb(new QGenericUnixFontDatabase())
+{
+ d_ptr = new QLinuxFbIntegrationPrivate();
+
+ // XXX
+ QString displaySpec = QString::fromLatin1(qgetenv("QWS_DISPLAY"));
+
+ if (!connect(displaySpec))
+ qFatal("QLinuxFbIntegration: could not initialize screen");
+ initDevice();
+
+ // Create a QImage directly on the screen's framebuffer.
+ // This is the blit target for copying windows to the screen.
+ mPrimaryScreen = new QLinuxFbScreen(data, w, h, lstep,
+ screenFormat);
+ mPrimaryScreen->setPhysicalSize(QSize(physWidth, physHeight));
+ mScreens.append(mPrimaryScreen);
+}
+
+QLinuxFbIntegration::~QLinuxFbIntegration()
+{
+ delete mPrimaryScreen;
+ delete d_ptr;
+}
+
+bool QLinuxFbIntegration::connect(const QString &displaySpec)
+{
+ const QStringList args = displaySpec.split(QLatin1Char(':'));
+
+ if (args.contains(QLatin1String("nographicsmodeswitch")))
+ d_ptr->doGraphicsMode = false;
+
+#ifdef QT_QWS_DEPTH_GENERIC
+ if (args.contains(QLatin1String("genericcolors")))
+ d_ptr->doGenericColors = true;
+#endif
+
+ QRegExp ttyRegExp(QLatin1String("tty=(.*)"));
+ if (args.indexOf(ttyRegExp) != -1)
+ d_ptr->ttyDevice = ttyRegExp.cap(1);
+
+#if 0
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+#ifndef QT_QWS_FRAMEBUFFER_LITTLE_ENDIAN
+ if (args.contains(QLatin1String("littleendian")))
+#endif
+ QScreen::setFrameBufferLittleEndian(true);
+#endif
+#endif
+
+ // Check for explicitly specified device
+ const int len = 8; // "/dev/fbx"
+ int m = displaySpec.indexOf(QLatin1String("/dev/fb"));
+
+ QString dev;
+ if (m > 0)
+ dev = displaySpec.mid(m, len);
+ else
+ dev = QLatin1String("/dev/fb0");
+
+ if (access(dev.toLatin1().constData(), R_OK|W_OK) == 0)
+ d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDWR);
+ if (d_ptr->fd == -1) {
+ if (access(dev.toLatin1().constData(), R_OK) == 0)
+ d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDONLY);
+ if (d_ptr->fd == 1) {
+ qWarning("Error opening framebuffer device %s", qPrintable(dev));
+ return false;
+ }
+ }
+
+ fb_fix_screeninfo finfo;
+ fb_var_screeninfo vinfo;
+ //#######################
+ // Shut up Valgrind
+ memset(&vinfo, 0, sizeof(vinfo));
+ memset(&finfo, 0, sizeof(finfo));
+ //#######################
+
+ /* Get fixed screen information */
+ if (d_ptr->fd != -1 && ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) {
+ perror("QLinuxFbIntegration::connect");
+ qWarning("Error reading fixed information");
+ return false;
+ }
+
+ if (finfo.type == FB_TYPE_VGA_PLANES) {
+ qWarning("VGA16 video mode not supported");
+ return false;
+ }
+
+ /* Get variable screen information */
+ if (d_ptr->fd != -1 && ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) {
+ perror("QLinuxFbIntegration::connect");
+ qWarning("Error reading variable information");
+ return false;
+ }
+
+ grayscale = vinfo.grayscale;
+ d = vinfo.bits_per_pixel;
+ if (d == 24) {
+ d = vinfo.red.length + vinfo.green.length + vinfo.blue.length;
+ if (d <= 0)
+ d = 24; // reset if color component lengths are not reported
+ } else if (d == 16) {
+ d = vinfo.red.length + vinfo.green.length + vinfo.blue.length;
+ if (d <= 0)
+ d = 16;
+ }
+ lstep = finfo.line_length;
+
+ int xoff = vinfo.xoffset;
+ int yoff = vinfo.yoffset;
+ const char* qwssize;
+ if((qwssize=::getenv("QWS_SIZE")) && sscanf(qwssize,"%dx%d",&w,&h)==2) {
+ if (d_ptr->fd != -1) {
+ if ((uint)w > vinfo.xres) w = vinfo.xres;
+ if ((uint)h > vinfo.yres) h = vinfo.yres;
+ }
+ dw=w;
+ dh=h;
+ int xxoff, yyoff;
+ if (sscanf(qwssize, "%*dx%*d+%d+%d", &xxoff, &yyoff) == 2) {
+ if (xxoff < 0 || xxoff + w > (int)(vinfo.xres))
+ xxoff = vinfo.xres - w;
+ if (yyoff < 0 || yyoff + h > (int)(vinfo.yres))
+ yyoff = vinfo.yres - h;
+ xoff += xxoff;
+ yoff += yyoff;
+ } else {
+ xoff += (vinfo.xres - w)/2;
+ yoff += (vinfo.yres - h)/2;
+ }
+ } else {
+ dw=w=vinfo.xres;
+ dh=h=vinfo.yres;
+ }
+
+ if (w == 0 || h == 0) {
+ qWarning("QLinuxFbIntegration::connect(): Unable to find screen geometry, "
+ "will use 320x240.");
+ dw = w = 320;
+ dh = h = 240;
+ }
+
+ setPixelFormat(vinfo);
+
+ // 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) {
+ if (vinfo.width != 0 && vinfo.height != 0
+ && vinfo.width != UINT_MAX && vinfo.height != UINT_MAX) {
+ physWidth = vinfo.width;
+ physHeight = vinfo.height;
+ } else {
+ const int dpi = 72;
+ physWidth = qRound(dw * 25.4 / dpi);
+ physHeight = qRound(dh * 25.4 / dpi);
+ }
+ }
+
+ dataoffset = yoff * lstep + xoff * d / 8;
+ //qDebug("Using %dx%dx%d screen",w,h,d);
+
+ /* Figure out the size of the screen in bytes */
+ size = h * lstep;
+
+ mapsize = finfo.smem_len;
+
+ data = (unsigned char *)-1;
+ if (d_ptr->fd != -1)
+ data = (unsigned char *)mmap(0, mapsize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, d_ptr->fd, 0);
+
+ if ((long)data == -1) {
+ perror("QLinuxFbIntegration::connect");
+ qWarning("Error: failed to map framebuffer device to memory.");
+ return false;
+ } else {
+ data += dataoffset;
+ }
+
+#if 0
+ canaccel = useOffscreen();
+ if(canaccel)
+ setupOffScreen();
+#endif
+ canaccel = false;
+
+ // Now read in palette
+ if((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4)) {
+ screencols= (vinfo.bits_per_pixel==8) ? 256 : 16;
+ int loopc;
+ fb_cmap startcmap;
+ startcmap.start=0;
+ startcmap.len=screencols;
+ startcmap.red=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+ startcmap.green=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+ startcmap.blue=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+ startcmap.transp=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+ if (d_ptr->fd == -1 || ioctl(d_ptr->fd, FBIOGETCMAP, &startcmap)) {
+ perror("QLinuxFbIntegration::connect");
+ qWarning("Error reading palette from framebuffer, using default palette");
+ createPalette(startcmap, vinfo, finfo);
+ }
+ int bits_used = 0;
+ for(loopc=0;loopc<screencols;loopc++) {
+ screenclut[loopc]=qRgb(startcmap.red[loopc] >> 8,
+ startcmap.green[loopc] >> 8,
+ startcmap.blue[loopc] >> 8);
+ bits_used |= startcmap.red[loopc]
+ | startcmap.green[loopc]
+ | startcmap.blue[loopc];
+ }
+ // WORKAROUND: Some framebuffer drivers only return 8 bit
+ // color values, so we need to not bit shift them..
+ if ((bits_used & 0x00ff) && !(bits_used & 0xff00)) {
+ for(loopc=0;loopc<screencols;loopc++) {
+ screenclut[loopc] = qRgb(startcmap.red[loopc],
+ startcmap.green[loopc],
+ startcmap.blue[loopc]);
+ }
+ qWarning("8 bits cmap returned due to faulty FB driver, colors corrected");
+ }
+ free(startcmap.red);
+ free(startcmap.green);
+ free(startcmap.blue);
+ free(startcmap.transp);
+ } else {
+ screencols=0;
+ }
+
+ return true;
+}
+
+bool QLinuxFbIntegration::initDevice()
+{
+ d_ptr->openTty();
+
+ // Grab current mode so we can reset it
+ fb_var_screeninfo vinfo;
+ fb_fix_screeninfo finfo;
+ //#######################
+ // Shut up Valgrind
+ memset(&vinfo, 0, sizeof(vinfo));
+ memset(&finfo, 0, sizeof(finfo));
+ //#######################
+
+ if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) {
+ perror("QLinuxFbScreen::initDevice");
+ qFatal("Error reading variable information in card init");
+ return false;
+ }
+
+#ifdef DEBUG_VINFO
+ qDebug("Greyscale %d",vinfo.grayscale);
+ qDebug("Nonstd %d",vinfo.nonstd);
+ qDebug("Red %d %d %d",vinfo.red.offset,vinfo.red.length,
+ vinfo.red.msb_right);
+ qDebug("Green %d %d %d",vinfo.green.offset,vinfo.green.length,
+ vinfo.green.msb_right);
+ qDebug("Blue %d %d %d",vinfo.blue.offset,vinfo.blue.length,
+ vinfo.blue.msb_right);
+ qDebug("Transparent %d %d %d",vinfo.transp.offset,vinfo.transp.length,
+ vinfo.transp.msb_right);
+#endif
+
+ d_ptr->startupw=vinfo.xres;
+ d_ptr->startuph=vinfo.yres;
+ d_ptr->startupd=vinfo.bits_per_pixel;
+ grayscale = vinfo.grayscale;
+
+ if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) {
+ perror("QLinuxFbScreen::initDevice");
+ qCritical("Error reading fixed information in card init");
+ // It's not an /error/ as such, though definitely a bad sign
+ // so we return true
+ return true;
+ }
+
+#ifdef __i386__
+ // Now init mtrr
+ if(!::getenv("QWS_NOMTRR")) {
+ int mfd=QT_OPEN("/proc/mtrr",O_WRONLY,0);
+ // MTRR entry goes away when file is closed - i.e.
+ // hopefully when QWS is killed
+ if(mfd != -1) {
+ mtrr_sentry sentry;
+ sentry.base=(unsigned long int)finfo.smem_start;
+ //qDebug("Physical framebuffer address %p",(void*)finfo.smem_start);
+ // Size needs to be in 4k chunks, but that's not always
+ // what we get thanks to graphics card registers. Write combining
+ // these is Not Good, so we write combine what we can
+ // (which is not much - 4 megs on an 8 meg card, it seems)
+ unsigned int size=finfo.smem_len;
+ size=size >> 22;
+ size=size << 22;
+ sentry.size=size;
+ sentry.type=MTRR_TYPE_WRCOMB;
+ if(ioctl(mfd,MTRRIOC_ADD_ENTRY,&sentry)==-1) {
+ //printf("Couldn't add mtrr entry for %lx %lx, %s\n",
+ //sentry.base,sentry.size,strerror(errno));
+ }
+ }
+
+ // Should we close mfd here?
+ //QT_CLOSE(mfd);
+ }
+#endif
+ if ((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4) || (finfo.visual==FB_VISUAL_DIRECTCOLOR))
+ {
+ fb_cmap cmap;
+ createPalette(cmap, vinfo, finfo);
+ if (ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap)) {
+ perror("QLinuxFbScreen::initDevice");
+ qWarning("Error writing palette to framebuffer");
+ }
+ free(cmap.red);
+ free(cmap.green);
+ free(cmap.blue);
+ free(cmap.transp);
+ }
+
+#if 0
+ if (canaccel) {
+ *entryp=0;
+ *lowest = mapsize;
+ insert_entry(*entryp, *lowest, *lowest); // dummy entry to mark start
+ }
+
+ shared->fifocount = 0;
+ shared->buffer_offset = 0xffffffff; // 0 would be a sensible offset (screen)
+ shared->linestep = 0;
+ shared->cliptop = 0xffffffff;
+ shared->clipleft = 0xffffffff;
+ shared->clipright = 0xffffffff;
+ shared->clipbottom = 0xffffffff;
+ shared->rop = 0xffffffff;
+#endif
+
+#ifdef QT_QWS_DEPTH_GENERIC
+ if (pixelFormat() == QImage::Format_Invalid && screencols == 0
+ && d_ptr->doGenericColors)
+ {
+ qt_set_generic_blit(this, vinfo.bits_per_pixel,
+ vinfo.red.length, vinfo.green.length,
+ vinfo.blue.length, vinfo.transp.length,
+ vinfo.red.offset, vinfo.green.offset,
+ vinfo.blue.offset, vinfo.transp.offset);
+ }
+#endif
+
+#if 0
+#ifndef QT_NO_QWS_CURSOR
+ QScreenCursor::initSoftwareCursor();
+#endif
+#endif
+ blank(false);
+
+ return true;
+}
+
+void QLinuxFbIntegration::setPixelFormat(struct fb_var_screeninfo info)
+{
+ const fb_bitfield rgba[4] = { info.red, info.green,
+ info.blue, info.transp };
+
+ QImage::Format format = QImage::Format_Invalid;
+
+ switch (d) {
+ case 32: {
+ const fb_bitfield argb8888[4] = {{16, 8, 0}, {8, 8, 0},
+ {0, 8, 0}, {24, 8, 0}};
+ const fb_bitfield abgr8888[4] = {{0, 8, 0}, {8, 8, 0},
+ {16, 8, 0}, {24, 8, 0}};
+ if (memcmp(rgba, argb8888, 4 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_ARGB32;
+ } else if (memcmp(rgba, argb8888, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB32;
+ } else if (memcmp(rgba, abgr8888, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB32;
+ pixeltype = BGRPixel;
+ }
+ break;
+ }
+ case 24: {
+ const fb_bitfield rgb888[4] = {{16, 8, 0}, {8, 8, 0},
+ {0, 8, 0}, {0, 0, 0}};
+ const fb_bitfield bgr888[4] = {{0, 8, 0}, {8, 8, 0},
+ {16, 8, 0}, {0, 0, 0}};
+ if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB888;
+ } else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB888;
+ pixeltype = BGRPixel;
+ }
+ break;
+ }
+ case 18: {
+ const fb_bitfield rgb666[4] = {{12, 6, 0}, {6, 6, 0},
+ {0, 6, 0}, {0, 0, 0}};
+ if (memcmp(rgba, rgb666, 3 * sizeof(fb_bitfield)) == 0)
+ format = QImage::Format_RGB666;
+ break;
+ }
+ case 16: {
+ const fb_bitfield rgb565[4] = {{11, 5, 0}, {5, 6, 0},
+ {0, 5, 0}, {0, 0, 0}};
+ const fb_bitfield bgr565[4] = {{0, 5, 0}, {5, 6, 0},
+ {11, 5, 0}, {0, 0, 0}};
+ if (memcmp(rgba, rgb565, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB16;
+ } else if (memcmp(rgba, bgr565, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB16;
+ pixeltype = BGRPixel;
+ }
+ break;
+ }
+ case 15: {
+ const fb_bitfield rgb1555[4] = {{10, 5, 0}, {5, 5, 0},
+ {0, 5, 0}, {15, 1, 0}};
+ const fb_bitfield bgr1555[4] = {{0, 5, 0}, {5, 5, 0},
+ {10, 5, 0}, {15, 1, 0}};
+ if (memcmp(rgba, rgb1555, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB555;
+ } else if (memcmp(rgba, bgr1555, 3 * sizeof(fb_bitfield)) == 0) {
+ format = QImage::Format_RGB555;
+ pixeltype = BGRPixel;
+ }
+ break;
+ }
+ case 12: {
+ const fb_bitfield rgb444[4] = {{8, 4, 0}, {4, 4, 0},
+ {0, 4, 0}, {0, 0, 0}};
+ if (memcmp(rgba, rgb444, 3 * sizeof(fb_bitfield)) == 0)
+ format = QImage::Format_RGB444;
+ break;
+ }
+ case 8:
+ break;
+ case 1:
+ format = QImage::Format_Mono; //###: LSB???
+ break;
+ default:
+ break;
+ }
+
+ screenFormat = format;
+}
+
+void QLinuxFbIntegration::createPalette(fb_cmap &cmap, fb_var_screeninfo &vinfo, fb_fix_screeninfo &finfo)
+{
+ if((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4)) {
+ screencols= (vinfo.bits_per_pixel==8) ? 256 : 16;
+ cmap.start=0;
+ cmap.len=screencols;
+ cmap.red=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+ cmap.green=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+ cmap.blue=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+ cmap.transp=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*screencols);
+
+ if (screencols==16) {
+ if (finfo.type == FB_TYPE_PACKED_PIXELS) {
+ // We'll setup a grayscale cmap for 4bpp linear
+ int val = 0;
+ for (int idx = 0; idx < 16; ++idx, val += 17) {
+ cmap.red[idx] = (val<<8)|val;
+ cmap.green[idx] = (val<<8)|val;
+ cmap.blue[idx] = (val<<8)|val;
+ screenclut[idx]=qRgb(val, val, val);
+ }
+ } else {
+ // Default 16 colour palette
+ // Green is now trolltech green so certain images look nicer
+ // black d_gray l_gray white red green blue cyan magenta yellow
+ unsigned char reds[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0xFF, 0xA2, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x82 };
+ unsigned char greens[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0xC5, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F };
+ unsigned char blues[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0x11, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x7F, 0x00, 0x00 };
+
+ for (int idx = 0; idx < 16; ++idx) {
+ cmap.red[idx] = ((reds[idx]) << 8)|reds[idx];
+ cmap.green[idx] = ((greens[idx]) << 8)|greens[idx];
+ cmap.blue[idx] = ((blues[idx]) << 8)|blues[idx];
+ cmap.transp[idx] = 0;
+ screenclut[idx]=qRgb(reds[idx], greens[idx], blues[idx]);
+ }
+ }
+ } else {
+ if (grayscale) {
+ // Build grayscale palette
+ int i;
+ for(i=0;i<screencols;++i) {
+ int bval = screencols == 256 ? i : (i << 4);
+ ushort val = (bval << 8) | bval;
+ cmap.red[i] = val;
+ cmap.green[i] = val;
+ cmap.blue[i] = val;
+ cmap.transp[i] = 0;
+ screenclut[i] = qRgb(bval,bval,bval);
+ }
+ } else {
+ // 6x6x6 216 color cube
+ int idx = 0;
+ for(int ir = 0x0; ir <= 0xff; ir+=0x33) {
+ for(int ig = 0x0; ig <= 0xff; ig+=0x33) {
+ for(int ib = 0x0; ib <= 0xff; ib+=0x33) {
+ cmap.red[idx] = (ir << 8)|ir;
+ cmap.green[idx] = (ig << 8)|ig;
+ cmap.blue[idx] = (ib << 8)|ib;
+ cmap.transp[idx] = 0;
+ screenclut[idx]=qRgb(ir, ig, ib);
+ ++idx;
+ }
+ }
+ }
+ // Fill in rest with 0
+ for (int loopc=0; loopc<40; ++loopc) {
+ screenclut[idx]=0;
+ ++idx;
+ }
+ screencols=idx;
+ }
+ }
+ } else if(finfo.visual==FB_VISUAL_DIRECTCOLOR) {
+ cmap.start=0;
+ int rbits=0,gbits=0,bbits=0;
+ switch (vinfo.bits_per_pixel) {
+ case 8:
+ rbits=vinfo.red.length;
+ gbits=vinfo.green.length;
+ bbits=vinfo.blue.length;
+ if(rbits==0 && gbits==0 && bbits==0) {
+ // cyber2000 driver bug hack
+ rbits=3;
+ gbits=3;
+ bbits=2;
+ }
+ break;
+ case 15:
+ rbits=5;
+ gbits=5;
+ bbits=5;
+ break;
+ case 16:
+ rbits=5;
+ gbits=6;
+ bbits=5;
+ break;
+ case 18:
+ case 19:
+ rbits=6;
+ gbits=6;
+ bbits=6;
+ break;
+ case 24: case 32:
+ rbits=gbits=bbits=8;
+ break;
+ }
+ screencols=cmap.len=1<<qMax(rbits,qMax(gbits,bbits));
+ cmap.red=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*256);
+ cmap.green=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*256);
+ cmap.blue=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*256);
+ cmap.transp=(unsigned short int *)
+ malloc(sizeof(unsigned short int)*256);
+ for(unsigned int i = 0x0; i < cmap.len; i++) {
+ cmap.red[i] = i*65535/((1<<rbits)-1);
+ cmap.green[i] = i*65535/((1<<gbits)-1);
+ cmap.blue[i] = i*65535/((1<<bbits)-1);
+ cmap.transp[i] = 0;
+ }
+ }
+}
+
+void QLinuxFbIntegration::blank(bool on)
+{
+ if (d_ptr->blank == on)
+ return;
+
+#if defined(QT_QWS_IPAQ)
+ if (on)
+ system("apm -suspend");
+#else
+ if (d_ptr->fd == -1)
+ return;
+// Some old kernel versions don't have this. These defines should go
+// away eventually
+#if defined(FBIOBLANK)
+#if defined(VESA_POWERDOWN) && defined(VESA_NO_BLANKING)
+ ioctl(d_ptr->fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING);
+#else
+ ioctl(d_ptr->fd, FBIOBLANK, on ? 1 : 0);
+#endif
+#endif
+#endif
+
+ d_ptr->blank = on;
+}
+
+bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+
+QPixmapData *QLinuxFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QWindowSurface *QLinuxFbIntegration::createWindowSurface(QWidget *widget, WId) const
+{
+ QFbWindowSurface * surface =
+ new QFbWindowSurface(mPrimaryScreen, widget);
+ return surface;
+}
+
+QPlatformWindow *QLinuxFbIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
+{
+ QFbWindow *w = new QFbWindow(widget);
+ mPrimaryScreen->addWindow(w);
+ return w;
+}
+
+QPlatformFontDatabase *QLinuxFbIntegration::fontDatabase() const
+{
+ return fontDb;
+}
+
+QLinuxFbScreen::QLinuxFbScreen(uchar * d, int w,
+ int h, int lstep, QImage::Format screenFormat) : compositePainter(0)
+{
+ data = d;
+ mGeometry = QRect(0,0,w,h);
+ bytesPerLine = lstep;
+ mFormat = screenFormat;
+ mDepth = 16;
+ mScreenImage = new QImage(mGeometry.width(), mGeometry.height(),
+ mFormat);
+ mFbScreenImage = new QImage(data, mGeometry.width(), mGeometry.height(),
+ bytesPerLine, mFormat);
+ cursor = new QPlatformSoftwareCursor(this);
+}
+
+void QLinuxFbScreen::setGeometry(QRect rect)
+{
+ mGeometry = rect;
+ delete mFbScreenImage;
+ mFbScreenImage = new QImage(data, mGeometry.width(), mGeometry.height(),
+ bytesPerLine, mFormat);
+ delete compositePainter;
+ compositePainter = 0;
+
+ delete mScreenImage;
+ mScreenImage = new QImage(mGeometry.width(), mGeometry.height(),
+ mFormat);
+}
+
+void QLinuxFbScreen::setFormat(QImage::Format format)
+{
+ mFormat = format;
+ delete mFbScreenImage;
+ mFbScreenImage = new QImage(data, mGeometry.width(), mGeometry.height(),
+ bytesPerLine, mFormat);
+ delete compositePainter;
+ compositePainter = 0;
+
+ delete mScreenImage;
+ mScreenImage = new QImage(mGeometry.width(), mGeometry.height(),
+ mFormat);
+}
+
+QRegion QLinuxFbScreen::doRedraw()
+{
+ QRegion touched;
+ touched = QFbScreen::doRedraw();
+
+ if (!compositePainter) {
+ compositePainter = new QPainter(mFbScreenImage);
+ }
+
+ QVector<QRect> rects = touched.rects();
+ for (int i = 0; i < rects.size(); i++)
+ compositePainter->drawImage(rects[i], *mScreenImage, rects[i]);
+ return touched;
+}
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
new file mode 100644
index 0000000000..f361843c6f
--- /dev/null
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** 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 QGRAPHICSSYSTEM_LINUXFB_H
+#define QGRAPHICSSYSTEM_LINUXFB_H
+
+#include <QPlatformIntegration>
+#include "../fb_base/fb_base.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLinuxFbScreen : public QFbScreen
+{
+ Q_OBJECT
+public:
+ QLinuxFbScreen(uchar * d, int w, int h, int lstep, QImage::Format screenFormat);
+ void setGeometry(QRect rect);
+ void setFormat(QImage::Format format);
+
+public slots:
+ QRegion doRedraw();
+
+private:
+ QImage * mFbScreenImage;
+ uchar * data;
+ int bytesPerLine;
+
+ QPainter *compositePainter;
+};
+
+class QLinuxFbIntegrationPrivate;
+struct fb_cmap;
+struct fb_var_screeninfo;
+struct fb_fix_screeninfo;
+
+class QLinuxFbIntegration : public QPlatformIntegration
+{
+public:
+ QLinuxFbIntegration();
+ ~QLinuxFbIntegration();
+
+ 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; }
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+private:
+ QLinuxFbScreen *mPrimaryScreen;
+ QList<QPlatformScreen *> mScreens;
+ QLinuxFbIntegrationPrivate *d_ptr;
+
+ enum PixelType { NormalPixel, BGRPixel };
+
+ QRgb screenclut[256];
+ int screencols;
+
+ uchar * data;
+
+ QImage::Format screenFormat;
+ int w;
+ int lstep;
+ int h;
+ int d;
+ PixelType pixeltype;
+ bool grayscale;
+
+ int dw;
+ int dh;
+
+ int size; // Screen size
+ int mapsize; // Total mapped memory
+
+ int displayId;
+
+ int physWidth;
+ int physHeight;
+
+ bool canaccel;
+ int dataoffset;
+ int cacheStart;
+
+ bool connect(const QString &displaySpec);
+ bool initDevice();
+ void setPixelFormat(struct fb_var_screeninfo);
+ void createPalette(fb_cmap &cmap, fb_var_screeninfo &vinfo, fb_fix_screeninfo &finfo);
+ void blank(bool on);
+ QPlatformFontDatabase *fontDb;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/minimal/main.cpp b/src/plugins/platforms/minimal/main.cpp
new file mode 100644
index 0000000000..b15f1832f3
--- /dev/null
+++ b/src/plugins/platforms/minimal/main.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 <QtGui/QPlatformIntegrationPlugin>
+#include "qminimalintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QMinimalIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QMinimalIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "Minimal";
+ return list;
+}
+
+QPlatformIntegration *QMinimalIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "minimal")
+ return new QMinimalIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(minimal, QMinimalIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro
new file mode 100644
index 0000000000..438a88e95f
--- /dev/null
+++ b/src/plugins/platforms/minimal/minimal.pro
@@ -0,0 +1,13 @@
+TARGET = qminimal
+include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+SOURCES = main.cpp \
+ qminimalintegration.cpp \
+ qminimalwindowsurface.cpp
+HEADERS = qminimalintegration.h \
+ qminimalwindowsurface.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp
new file mode 100644
index 0000000000..3a545e4e5c
--- /dev/null
+++ b/src/plugins/platforms/minimal/qminimalintegration.cpp
@@ -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$
+** 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 "qminimalintegration.h"
+#include "qminimalwindowsurface.h"
+
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/QPlatformWindow>
+
+QMinimalIntegration::QMinimalIntegration()
+{
+ QMinimalScreen *mPrimaryScreen = new QMinimalScreen();
+
+ mPrimaryScreen->mGeometry = QRect(0, 0, 240, 320);
+ mPrimaryScreen->mDepth = 16;
+ mPrimaryScreen->mFormat = QImage::Format_RGB16;
+
+ mScreens.append(mPrimaryScreen);
+}
+
+bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPixmapData *QMinimalIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QPlatformWindow *QMinimalIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QPlatformWindow(widget);
+}
+
+QWindowSurface *QMinimalIntegration::createWindowSurface(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QMinimalWindowSurface(widget);
+}
diff --git a/src/plugins/platforms/minimal/qminimalintegration.h b/src/plugins/platforms/minimal/qminimalintegration.h
new file mode 100644
index 0000000000..5f93443b8c
--- /dev/null
+++ b/src/plugins/platforms/minimal/qminimalintegration.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$
+** 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 QPLATFORMINTEGRATION_MINIMAL_H
+#define QPLATFORMINTEGRATION_MINIMAL_H
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_NAMESPACE
+
+class QMinimalScreen : public QPlatformScreen
+{
+public:
+ QMinimalScreen()
+ : mDepth(16), mFormat(QImage::Format_RGB16) {}
+
+ QRect geometry() const { return mGeometry; }
+ int depth() const { return mDepth; }
+ QImage::Format format() const { return mFormat; }
+
+public:
+ QRect mGeometry;
+ int mDepth;
+ QImage::Format mFormat;
+ QSize mPhysicalSize;
+};
+
+class QMinimalIntegration : public QPlatformIntegration
+{
+public:
+ QMinimalIntegration();
+
+ 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; }
+
+private:
+ QList<QPlatformScreen *> mScreens;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/minimal/qminimalwindowsurface.cpp b/src/plugins/platforms/minimal/qminimalwindowsurface.cpp
new file mode 100644
index 0000000000..dd8c9b7045
--- /dev/null
+++ b/src/plugins/platforms/minimal/qminimalwindowsurface.cpp
@@ -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$
+** 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 "qminimalwindowsurface.h"
+#include <QtCore/qdebug.h>
+#include <QtGui/private/qapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QMinimalWindowSurface::QMinimalWindowSurface(QWidget *window)
+ : QWindowSurface(window)
+{
+ //qDebug() << "QMinimalWindowSurface::QMinimalWindowSurface:" << (long)this;
+}
+
+QMinimalWindowSurface::~QMinimalWindowSurface()
+{
+}
+
+QPaintDevice *QMinimalWindowSurface::paintDevice()
+{
+ //qDebug() << "QMinimalWindowSurface::paintDevice";
+ return &mImage;
+}
+
+void QMinimalWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ 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();
+ mImage.save(filename);
+}
+
+void QMinimalWindowSurface::resize(const QSize &size)
+{
+ //qDebug() << "QMinimalWindowSurface::setGeometry:" << (long)this << rect;
+ QWindowSurface::resize(size);
+ QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
+ if (mImage.size() != size)
+ mImage = QImage(size, format);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimal/qminimalwindowsurface.h b/src/plugins/platforms/minimal/qminimalwindowsurface.h
new file mode 100644
index 0000000000..bfeeacadc9
--- /dev/null
+++ b/src/plugins/platforms/minimal/qminimalwindowsurface.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 QWINDOWSURFACE_MINIMAL_H
+#define QWINDOWSURFACE_MINIMAL_H
+
+#include <QtGui/private/qwindowsurface_p.h>
+
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QMinimalWindowSurface : public QWindowSurface
+{
+public:
+ QMinimalWindowSurface(QWidget *window);
+ ~QMinimalWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size);
+
+private:
+ QImage mImage;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/openkode/main.cpp b/src/plugins/platforms/openkode/main.cpp
new file mode 100644
index 0000000000..ead17a4598
--- /dev/null
+++ b/src/plugins/platforms/openkode/main.cpp
@@ -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$
+** 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 <QtGui/QPlatformIntegrationPlugin>
+#include "qopenkodeintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QOpenKODEPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QOpenKODEPlugin::keys() const
+{
+ QStringList list;
+ list << "OpenKODE";
+ return list;
+}
+
+QPlatformIntegration * QOpenKODEPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "openkode")
+ return new QOpenKODEIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(openkode, QOpenKODEPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/openkode.pro b/src/plugins/platforms/openkode/openkode.pro
new file mode 100644
index 0000000000..c8ae4154c3
--- /dev/null
+++ b/src/plugins/platforms/openkode/openkode.pro
@@ -0,0 +1,42 @@
+TARGET = qopenkodeintegration
+include(../../qpluginbase.pri)
+
+QT += opengl
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+SOURCES = main.cpp \
+ qopenkodeintegration.cpp \
+ qopenkodewindow.cpp \
+ ../eglconvenience/qeglplatformcontext.cpp \
+ ../eglconvenience/qeglconvenience.cpp \
+ qopenkodeeventloopintegration.cpp
+
+HEADERS = qopenkodeintegration.h \
+ qopenkodewindow.h \
+ ../eglconvenience/qeglplatformcontext.h \
+ ../eglconvenience/qeglconvenience.h \
+ qopenkodeeventloopintegration.h \
+ openkodekeytranslator.h
+
+include (../fontdatabases/genericunix/genericunix.pri)
+
+RESOURCES = resources.qrc
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
+
+LIBS += -lKD -lEGL
+!isEmpty(QMAKE_INCDIR_OPENGL_ES2){
+ INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2
+}
+!isEmpty(QMAKE_LIBDIR_OPENGL_ES2){
+ for(p, QMAKE_LIBDIR_OPENGL_ES2) {
+ exists($$p):LIBS += -L$$p
+ }
+}
+!isEmpty(QMAKE_LIBS_OPENGL_ES2){
+ LIBS += $$QMAKE_LIBS_OPENGL_ES2
+} else {
+ LIBS += -lGLESv2
+}
diff --git a/src/plugins/platforms/openkode/openkodekeytranslator.h b/src/plugins/platforms/openkode/openkodekeytranslator.h
new file mode 100644
index 0000000000..502bf03942
--- /dev/null
+++ b/src/plugins/platforms/openkode/openkodekeytranslator.h
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** 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 OPENKODEKEYTRANSLATOR_H
+#define OPENKODEKEYTRANSLATOR_H
+
+#ifdef KD_ATX_keyboard
+
+#include <KD/ATX_keyboard.h>
+
+QT_BEGIN_NAMESPACE
+
+Qt::Key keyTranslator( int key )
+{
+ switch (key) {
+// KD_KEY_ACCEPT_ATX:
+// KD_KEY_AGAIN_ATX:
+// KD_KEY_ALLCANDIDATES_ATX
+// KD_KEY_ALPHANUMERIC_ATX
+ case KD_KEY_ALT_ATX:
+ return Qt::Key_Alt;
+ case KD_KEY_ALTGRAPH_ATX:
+ return Qt::Key_AltGr;
+// KD_KEY_APPS_ATX
+// KD_KEY_ATTN_ATX
+// KD_KEY_BROWSERBACK_ATX
+// KD_KEY_BROWSERFAVORITES_ATX
+// KD_KEY_BROWSERFORWARD_ATX
+// KD_KEY_BROWSERHOME_ATX
+// KD_KEY_BROWSERREFRESH_ATX
+// KD_KEY_BROWSERSEARCH_ATX
+// KD_KEY_BROWSERSTOP_ATX
+ case KD_KEY_CAPSLOCK_ATX:
+ return Qt::Key_CapsLock;
+ case KD_KEY_CLEAR_ATX:
+ return Qt::Key_Clear;
+ case KD_KEY_CODEINPUT_ATX:
+ return Qt::Key_Codeinput;
+// KD_KEY_COMPOSE_ATX
+ case KD_KEY_CONTROL_ATX:
+ return Qt::Key_Control;
+// KD_KEY_CRSEL_ATX
+// KD_KEY_CONVERT_ATX
+ case KD_KEY_COPY_ATX:
+ return Qt::Key_Copy;
+ case KD_KEY_CUT_ATX:
+ return Qt::Key_Cut;
+ case KD_KEY_DOWN_ATX:
+ return Qt::Key_Down;
+ case KD_KEY_END_ATX:
+ return Qt::Key_End;
+ case KD_KEY_ENTER_ATX:
+ return Qt::Key_Enter;
+// KD_KEY_ERASEEOF_ATX
+// KD_KEY_EXECUTE_ATX
+// KD_KEY_EXSEL_ATX
+ case KD_KEY_F1_ATX:
+ return Qt::Key_F1;
+ case KD_KEY_F2_ATX:
+ return Qt::Key_F2;
+ case KD_KEY_F3_ATX:
+ return Qt::Key_F3;
+ case KD_KEY_F4_ATX:
+ return Qt::Key_F4;
+ case KD_KEY_F5_ATX:
+ return Qt::Key_F5;
+ case KD_KEY_F6_ATX:
+ return Qt::Key_F6;
+ case KD_KEY_F7_ATX:
+ return Qt::Key_F7;
+ case KD_KEY_F8_ATX:
+ return Qt::Key_F8;
+ case KD_KEY_F9_ATX:
+ return Qt::Key_F9;
+ case KD_KEY_F10_ATX:
+ return Qt::Key_F10;
+ case KD_KEY_F11_ATX:
+ return Qt::Key_F11;
+ case KD_KEY_F12_ATX:
+ return Qt::Key_F12;
+ case KD_KEY_F13_ATX:
+ return Qt::Key_F13;
+ case KD_KEY_F14_ATX:
+ return Qt::Key_F14;
+ case KD_KEY_F15_ATX:
+ return Qt::Key_F15;
+ case KD_KEY_F16_ATX:
+ return Qt::Key_F16;
+ case KD_KEY_F17_ATX:
+ return Qt::Key_F17;
+ case KD_KEY_F18_ATX:
+ return Qt::Key_F18;
+ case KD_KEY_F19_ATX:
+ return Qt::Key_F19;
+ case KD_KEY_F20_ATX:
+ return Qt::Key_F20;
+ case KD_KEY_F21_ATX:
+ return Qt::Key_F21;
+ case KD_KEY_F22_ATX:
+ return Qt::Key_F22;
+ case KD_KEY_F23_ATX:
+ return Qt::Key_F23;
+ case KD_KEY_F24_ATX:
+ return Qt::Key_F24;
+// KD_KEY_FINALMODE_ATX
+// KD_KEY_FIND_ATX
+// KD_KEY_FULLWIDTH_ATX
+// KD_KEY_HALFWIDTH_ATX
+ case KD_KEY_HANGULMODE_ATX:
+ return Qt::Key_Hangul;
+// KD_KEY_HANJAMODE_ATX
+ case KD_KEY_HELP_ATX:
+ return Qt::Key_Help;
+ case KD_KEY_HIRAGANA_ATX:
+ return Qt::Key_Hiragana;
+ case KD_KEY_HOME_ATX:
+ return Qt::Key_Home;
+ case KD_KEY_INSERT_ATX:
+ return Qt::Key_Insert;
+// KD_KEY_JAPANESEHIRAGANA_ATX:
+// KD_KEY_JAPANESEKATAKANA_ATX
+// KD_KEY_JAPANESEROMAJI_ATX
+// KD_KEY_JUNJAMODE_ATX
+ case KD_KEY_KANAMODE_ATX:
+ return Qt::Key_Kana_Lock; //?
+ case KD_KEY_KANJIMODE_ATX:
+ return Qt::Key_Kanji;
+// KD_KEY_KATAKANA_ATX
+// KD_KEY_LAUNCHAPPLICATION1_ATX
+// KD_KEY_LAUNCHAPPLICATION2_ATX
+ case KD_KEY_LAUNCHMAIL_ATX:
+ return Qt::Key_MailForward;
+ case KD_KEY_LEFT_ATX:
+ return Qt::Key_Left;
+ case KD_KEY_META_ATX:
+ return Qt::Key_Meta;
+ case KD_KEY_MEDIANEXTTRACK_ATX:
+ return Qt::Key_MediaNext;
+ case KD_KEY_MEDIAPLAYPAUSE_ATX:
+ return Qt::Key_MediaPause;
+ case KD_KEY_MEDIAPREVIOUSTRACK_ATX:
+ return Qt::Key_MediaPrevious;
+ case KD_KEY_MEDIASTOP_ATX:
+ return Qt::Key_MediaStop;
+ case KD_KEY_MODECHANGE_ATX:
+ return Qt::Key_Mode_switch;
+// KD_KEY_NONCONVERT_ATX
+ case KD_KEY_NUMLOCK_ATX:
+ return Qt::Key_NumLock;
+ case KD_KEY_PAGEDOWN_ATX:
+ return Qt::Key_PageDown;
+ case KD_KEY_PAGEUP_ATX:
+ return Qt::Key_PageUp;
+ case KD_KEY_PASTE_ATX:
+ return Qt::Key_Paste;
+ case KD_KEY_PAUSE_ATX:
+ return Qt::Key_Pause;
+ case KD_KEY_PLAY_ATX:
+ return Qt::Key_Play;
+// KD_KEY_PREVIOUSCANDIDATE_ATX
+ case KD_KEY_PRINTSCREEN_ATX:
+ return Qt::Key_Print;
+// case KD_KEY_PROCESS_ATX
+// case KD_KEY_PROPS_ATX
+ case KD_KEY_RIGHT_ATX:
+ return Qt::Key_Right;
+// KD_KEY_ROMANCHARACTERS_ATX
+ case KD_KEY_SCROLL_ATX:
+ return Qt::Key_ScrollLock;
+ case KD_KEY_SELECT_ATX:
+ return Qt::Key_Select;
+// KD_KEY_SELECTMEDIA_ATX
+ case KD_KEY_SHIFT_ATX:
+ return Qt::Key_Shift;
+ case KD_KEY_STOP_ATX:
+ return Qt::Key_Stop;
+ case KD_KEY_UP_ATX:
+ return Qt::Key_Up;
+// KD_KEY_UNDO_ATX
+ case KD_KEY_VOLUMEDOWN_ATX:
+ return Qt::Key_VolumeDown;
+ case KD_KEY_VOLUMEMUTE_ATX:
+ return Qt::Key_VolumeMute;
+ case KD_KEY_VOLUMEUP_ATX:
+ return Qt::Key_VolumeUp;
+ case KD_KEY_WIN_ATX:
+ return Qt::Key_Meta;
+ case KD_KEY_ZOOM_ATX:
+ return Qt::Key_Zoom;
+ case 0x8:
+ return Qt::Key_Backspace;
+ case 0x1b:
+ return Qt::Key_Escape;
+ case 0x9:
+ return Qt::Key_Tab;
+
+ default:
+ break;
+ }
+
+ return Qt::Key_Escape;
+}
+
+QT_END_NAMESPACE
+#endif //KD_ATX_keyboard
+#endif // OPENKODEKEYTRANSLATOR_H
diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp
new file mode 100644
index 0000000000..4ca82db338
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** 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 "qopenkodeeventloopintegration.h"
+
+#include <QDebug>
+
+#include <KD/kd.h>
+#include <KD/ATX_keyboard.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int QT_EVENT_WAKEUP_EVENTLOOP = KD_EVENT_USER + 1;
+
+void kdprocessevent( const KDEvent *event)
+{
+ switch (event->type) {
+ case KD_EVENT_INPUT:
+ qDebug() << "KD_EVENT_INPUT";
+ break;
+ case KD_EVENT_INPUT_POINTER:
+ qDebug() << "KD_EVENT_INPUT_POINTER";
+ break;
+ case KD_EVENT_WINDOW_CLOSE:
+ qDebug() << "KD_EVENT_WINDOW_CLOSE";
+ break;
+ case KD_EVENT_WINDOWPROPERTY_CHANGE:
+ qDebug() << "KD_EVENT_WINDOWPROPERTY_CHANGE";
+ qDebug() << event->data.windowproperty.pname;
+ break;
+ case KD_EVENT_WINDOW_FOCUS:
+ qDebug() << "KD_EVENT_WINDOW_FOCUS";
+ break;
+ case KD_EVENT_WINDOW_REDRAW:
+ qDebug() << "KD_EVENT_WINDOW_REDRAW";
+ break;
+ case KD_EVENT_USER:
+ qDebug() << "KD_EVENT_USER";
+ break;
+ case KD_EVENT_INPUT_KEY_ATX:
+ qDebug() << "KD_EVENT_INPUT_KEY_ATX";
+ break;
+ case QT_EVENT_WAKEUP_EVENTLOOP:
+ QPlatformEventLoopIntegration::processEvents();
+ break;
+ default:
+ break;
+ }
+
+ kdDefaultEvent(event);
+
+}
+
+QOpenKODEEventLoopIntegration::QOpenKODEEventLoopIntegration()
+ : m_quit(false)
+{
+ m_kdThread = kdThreadSelf();
+ kdInstallCallback(&kdprocessevent,QT_EVENT_WAKEUP_EVENTLOOP,this);
+}
+
+void QOpenKODEEventLoopIntegration::startEventLoop()
+{
+
+ while(!m_quit) {
+ qint64 msec = nextTimerEvent();
+ const KDEvent *event = kdWaitEvent(msec);
+ if (event) {
+ kdDefaultEvent(event);
+ while ((event = kdWaitEvent(0)) != 0) {
+ kdDefaultEvent(event);
+ }
+ }
+ QPlatformEventLoopIntegration::processEvents();
+ }
+}
+
+void QOpenKODEEventLoopIntegration::quitEventLoop()
+{
+ m_quit = true;
+}
+
+void QOpenKODEEventLoopIntegration::qtNeedsToProcessEvents()
+{
+ KDEvent *event = kdCreateEvent();
+ event->type = QT_EVENT_WAKEUP_EVENTLOOP;
+ event->userptr = this;
+ kdPostThreadEvent(event,m_kdThread);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h
new file mode 100644
index 0000000000..cef3465123
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.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$
+** 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 QOPENKODEEVENTLOOPINTEGRATION_H
+#define QOPENKODEEVENTLOOPINTEGRATION_H
+
+#include <QtGui/QPlatformEventLoopIntegration>
+
+class KDThread;
+class KDEvent;
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+class QOpenKODEEventLoopIntegration : public QPlatformEventLoopIntegration
+{
+public:
+ QOpenKODEEventLoopIntegration();
+ void startEventLoop();
+ void quitEventLoop();
+ void qtNeedsToProcessEvents();
+
+ void processInputEvent(const KDEvent *event);
+private:
+
+ bool m_quit;
+ KDThread *m_kdThread;
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QOPENKODEEVENTLOOPINTEGRATION_H
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
new file mode 100644
index 0000000000..703b1a9832
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** 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 "qopenkodeintegration.h"
+#include "qopenkodewindow.h"
+#include "qopenkodeeventloopintegration.h"
+
+#include <QtOpenGL/private/qpixmapdata_gl_p.h>
+#include <QtOpenGL/private/qwindowsurface_gl_p.h>
+
+#include <QtGui/private/qpixmap_raster_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qfile.h>
+
+#include "qgenericunixfontdatabase.h"
+
+#include <KD/kd.h>
+#include <KD/NV_display.h>
+#include <KD/NV_initialize.h>
+
+#include <EGL/egl.h>
+
+#include "GLES2/gl2ext.h"
+
+QT_BEGIN_NAMESPACE
+
+QOpenKODEScreen::QOpenKODEScreen(KDDisplayNV *kdDisplay, KDDesktopNV *kdDesktop)
+ : mIsFullScreen(false)
+{
+ qDebug() << "QOpenKODEScreen::QOpenKODEIntegrationScreen()";
+
+ KDboolean enabled = KD_TRUE;
+ kdSetDisplayPropertybvNV(kdDisplay,
+ KD_DISPLAYPROPERTY_ENABLED_NV,
+ &enabled);
+ KDboolean power = KD_DISPLAY_POWER_ON;
+ kdSetDisplayPropertyivNV(kdDisplay,
+ KD_DISPLAYPROPERTY_POWER_NV,
+ &power);
+
+ kdSetDisplayPropertycvNV(kdDisplay,
+ KD_DISPLAYPROPERTY_DESKTOP_NAME_NV,
+ KD_DEFAULT_DESKTOP_NV);
+
+ KDDisplayModeNV mode;
+ if (kdGetDisplayModeNV(kdDisplay, &mode)) {
+ qErrnoWarning(kdGetError(), "Could not get display mode");
+ return;
+ }
+
+ qDebug() << " - display mode " << mode.width << "x" << mode.height << " refresh " << mode.refresh;
+
+ KDint desktopSize[] = { mode.width, mode.height };
+
+ if (kdSetDesktopPropertyivNV(kdDesktop, KD_DESKTOPPROPERTY_SIZE_NV, desktopSize)) {
+ qErrnoWarning(kdGetError(), "Could not set desktop size");
+ return;
+ }
+
+ // Once we've set up the desktop and display we don't need them anymore
+ kdReleaseDisplayNV(kdDisplay);
+ kdReleaseDesktopNV(kdDesktop);
+
+ mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (mEglDisplay == EGL_NO_DISPLAY) {
+ qErrnoWarning("EGL failed to obtain display");
+ }
+
+ /* Initialize EGL display */
+ EGLBoolean rvbool = eglInitialize(mEglDisplay, 0, 0);
+ if (!rvbool) {
+ qErrnoWarning("EGL failed to initialize display");
+ }
+
+// cursor = new QOpenKODECursor(this);
+
+ mGeometry = QRect(0, 0, mode.width, mode.height);
+ mDepth = 24;
+ mFormat = QImage::Format_RGB32;
+
+
+}
+
+QOpenKODEIntegration::QOpenKODEIntegration()
+ : mEventLoopIntegration(0)
+ , mFontDb(new QGenericUnixFontDatabase())
+ , mMainGlContext(0)
+{
+ if (kdInitializeNV() == KD_ENOTINITIALIZED) {
+ qFatal("Did not manage to initialize openkode");
+ }
+
+ KDDisplaySystemNV *kdDisplaySystem = kdCreateDisplaySystemSnapshotNV(this);
+ KDint32 displayCount = 0;
+ kdGetDisplaySystemPropertyivNV(kdDisplaySystem, KD_DISPLAYPROPERTY_COUNT_NV, 0, &displayCount);
+
+ for (int i = 0; i < displayCount; i++) {
+ KDchar *displayName = 0;
+ KDsize displayNameLength = 0;
+ kdGetDisplaySystemPropertycvNV(kdDisplaySystem,KD_DISPLAYPROPERTY_NAME_NV,i,0,&displayNameLength);
+ if (!displayNameLength)
+ continue;
+ displayName = new KDchar[displayNameLength];
+ kdGetDisplaySystemPropertycvNV(kdDisplaySystem,KD_DISPLAYPROPERTY_NAME_NV,i,displayName,&displayNameLength);
+
+ KDDisplayNV *display = kdGetDisplayNV(displayName,this);
+ if (!display || display == (void*)-1) {
+ qErrnoWarning(kdGetError(), "Could not obtain KDDisplayNV pointer");
+ return;
+ }
+ if (displayNameLength)
+ delete displayName;
+
+ KDchar *desktopName = 0;
+ KDsize desktopNameLength = 0;
+ bool openkodeImpDoesNotFail = false;
+ if (openkodeImpDoesNotFail) {
+ qDebug() << "printing desktopname";
+ kdGetDisplayPropertycvNV(display,KD_DISPLAYPROPERTY_DESKTOP_NAME_NV,desktopName,&desktopNameLength);
+ if (desktopNameLength) {
+ desktopName = new KDchar[desktopNameLength];
+ kdGetDisplayPropertycvNV(display,KD_DISPLAYPROPERTY_DESKTOP_NAME_NV,desktopName,&desktopNameLength);
+ } else {
+ desktopName = KD_DEFAULT_DESKTOP_NV;
+ }
+ } else {
+ desktopName = KD_DEFAULT_DESKTOP_NV;
+ }
+
+ KDDesktopNV *desktop = kdGetDesktopNV(desktopName,this);
+ if (!desktop || desktop == (void*)-1) {
+ qErrnoWarning(kdGetError(), "Could not obtain KDDesktopNV pointer");
+ kdReleaseDisplayNV(display);
+ return;
+ }
+ if (desktopNameLength)
+ delete desktopName;
+
+ QOpenKODEScreen *screen = new QOpenKODEScreen(display,desktop);
+ mScreens.append(screen);
+ }
+}
+
+QOpenKODEIntegration::~QOpenKODEIntegration()
+{
+ delete mEventLoopIntegration;
+ delete mFontDb;
+}
+
+
+bool QOpenKODEIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPixmapData *QOpenKODEIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QGLPixmapData(type);
+}
+
+QPlatformWindow *QOpenKODEIntegration::createPlatformWindow(QWidget *tlw, WId ) const
+{
+ return new QOpenKODEWindow(tlw);
+}
+
+QWindowSurface *QOpenKODEIntegration::createWindowSurface(QWidget *widget, WId) const
+{
+ QWindowSurface *returnSurface = 0;
+ switch (widget->platformWindowFormat().windowApi()) {
+
+ case QPlatformWindowFormat::Raster:
+ case QPlatformWindowFormat::OpenGL:
+ returnSurface = new QGLWindowSurface(widget);
+ break;
+
+ case QPlatformWindowFormat::OpenVG:
+// returnSurface = new QVGWindowSurface(widget);
+// break;
+
+ default:
+ returnSurface = new QGLWindowSurface(widget);
+ break;
+ }
+
+ return returnSurface;
+}
+
+QPlatformEventLoopIntegration *QOpenKODEIntegration::createEventLoopIntegration() const
+{
+ if (!mEventLoopIntegration) {
+ QOpenKODEIntegration *that = const_cast<QOpenKODEIntegration *>(this);
+ that->mEventLoopIntegration = new QOpenKODEEventLoopIntegration;
+ }
+ return mEventLoopIntegration;
+}
+
+QPlatformFontDatabase *QOpenKODEIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.h b/src/plugins/platforms/openkode/qopenkodeintegration.h
new file mode 100644
index 0000000000..d5aac98c02
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** 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 QGRAPHICSSYSTEM_OPENKODE_H
+#define QGRAPHICSSYSTEM_OPENKODE_H
+
+#include "qopenkodeeventloopintegration.h"
+
+#include <QtCore/qsemaphore.h>
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformFontDatabase>
+
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+struct KDDesktopNV;
+struct KDDisplayNV;
+class QOpenKODECursor;
+
+class QOpenKODEScreen : public QPlatformScreen
+{
+ Q_OBJECT
+public:
+ QOpenKODEScreen(KDDisplayNV *kdDisplay, KDDesktopNV *kdDesktop);
+ ~QOpenKODEScreen() {}
+
+ QRect geometry() const { return mGeometry; }
+ int depth() const { return mDepth; }
+ QImage::Format format() const { return mFormat; }
+
+ EGLDisplay eglDisplay() { return mEglDisplay; }
+
+ bool isFullScreen() const {return mIsFullScreen;}
+ void setFullScreen(bool fullscreen) { mIsFullScreen = fullscreen; }
+private:
+ QRect mGeometry;
+ int mDepth;
+ QImage::Format mFormat;
+ EGLDisplay mEglDisplay;
+ bool mIsFullScreen;
+};
+
+class QOpenKODEIntegration : public QPlatformIntegration
+{
+public:
+ QOpenKODEIntegration();
+ ~QOpenKODEIntegration();
+
+ 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;
+
+ QPlatformEventLoopIntegration *createEventLoopIntegration() const;
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+ virtual QList<QPlatformScreen *> screens() const { return mScreens; }
+
+ static GLuint blitterProgram();
+
+ void setMainGLContext(QEGLPlatformContext *ctx) { mMainGlContext = ctx; }
+ void mainGLContext() const { return mMainGlContext; }
+
+private:
+ QList<QPlatformScreen *> mScreens;
+ QOpenKODEEventLoopIntegration *mEventLoopIntegration;
+ QPlatformFontDatabase *mFontDb;
+ QEGLPlatformContext *mMainGlContext;
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp
new file mode 100644
index 0000000000..d34dff8a34
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** 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 "qopenkodewindow.h"
+#include "qopenkodeintegration.h"
+#include "../eglconvenience/qeglplatformcontext.h"
+#include "../eglconvenience/qeglconvenience.h"
+
+#include <KD/kd.h>
+#include <KD/NV_display.h>
+#include <KD/kdplatform.h>
+#ifdef KD_ATX_keyboard
+#include "openkodekeytranslator.h"
+#endif
+
+#include <EGL/egl.h>
+
+#include <QtGui/qwidget.h>
+#include <QtGui/private/qwidget_p.h>
+#include <QtGui/private/qapplication_p.h>
+
+#include <QtCore/qvector.h>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+void kdProcessMouseEvents( const KDEvent *event )
+{
+ QOpenKODEWindow *window = static_cast<QOpenKODEWindow *>(event->userptr);
+ window->processMouseEvents(event);
+}
+
+#ifdef KD_ATX_keyboard
+void kdProcessKeyEvents( const KDEvent *event )
+{
+ QOpenKODEWindow *window = static_cast<QOpenKODEWindow *>(event->userptr);
+ window->processKeyEvents(event);
+}
+#endif //KD_ATX_keyboard
+
+QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw)
+ : QPlatformWindow(tlw), isFullScreen(false)
+{
+ if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenVG) {
+ m_eglApi = EGL_OPENVG_API;
+ } else {
+ m_eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ m_eglContextAttrs.append(2);
+
+ m_eglApi = EGL_OPENGL_ES_API;
+ }
+ eglBindAPI(m_eglApi);
+
+ m_eglContextAttrs.append(EGL_NONE);
+ m_eglWindowAttrs.append(EGL_NONE);
+
+ QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens();
+ //XXXX: jl figure out how to pick the correct screen.
+// Q_ASSERT(screens.size() > tlw->d_func()->screenNumber);
+// QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(tlw->d_func()->screenNumber));
+ QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0));
+ if (!screen) {
+ qErrnoWarning("Could not make QOpenKODEWindow without a screen");
+ }
+
+ QPlatformWindowFormat format = tlw->platformWindowFormat();
+ format.setRedBufferSize(5);
+ format.setGreenBufferSize(6);
+ format.setBlueBufferSize(5);
+
+ m_eglConfig = q_configFromQPlatformWindowFormat(screen->eglDisplay(),format);
+
+ m_kdWindow = kdCreateWindow(screen->eglDisplay(),
+ m_eglConfig,
+ this);
+ kdInstallCallback(kdProcessMouseEvents,KD_EVENT_INPUT_POINTER,this);
+#ifdef KD_ATX_keyboard
+ kdInstallCallback(kdProcessKeyEvents, KD_EVENT_INPUT_KEY_ATX,this);
+#endif //KD_ATX_keyboard
+
+ if (!m_kdWindow) {
+ qErrnoWarning(kdGetError(), "Error creating native window");
+ return;
+ }
+
+ KDboolean exclusive(false);
+ if (kdSetWindowPropertybv(m_kdWindow,KD_WINDOWPROPERTY_DESKTOP_EXCLUSIVE_NV, &exclusive)) {
+ isFullScreen = true;
+ }
+
+ if (isFullScreen) {
+ tlw->setGeometry(screen->geometry());
+ screen->setFullScreen(isFullScreen);
+ }else {
+ const KDint windowSize[2] = { tlw->width(), tlw->height() };
+ if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_SIZE, windowSize)) {
+ qErrnoWarning(kdGetError(), "Could not set native window size");
+ }
+ KDboolean visibillity(false);
+ if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visibillity)) {
+ qErrnoWarning(kdGetError(), "Could not set visibillity to false");
+ }
+
+ const KDint windowPos[2] = { tlw->x(), tlw->y() };
+ if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_DESKTOP_OFFSET_NV, windowPos)) {
+ qErrnoWarning(kdGetError(), "Could not set native window position");
+ return;
+ }
+ }
+
+
+ QOpenKODEIntegration *integration = static_cast<QOpenKODEIntegration *>(QApplicationPrivate::platformIntegration());
+
+ if (!isFullScreen || (isFullScreen && !integration->mainGLContext())) {
+ if (kdRealizeWindow(m_kdWindow, &m_eglWindow)) {
+ qErrnoWarning(kdGetError(), "Could not realize native window");
+ return;
+ }
+
+ EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData());
+ m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(), m_eglConfig,
+ m_eglContextAttrs.data(), surface, m_eglApi);
+ integration->setMainGLContext(m_platformGLContext);
+ } else {
+ m_platformGlContext = integration->mainGLContext();
+ kdDestroyWindow(m_kdWindow);
+ m_kdWindow = 0;
+ }
+}
+
+
+QOpenKODEWindow::~QOpenKODEWindow()
+{
+ if (m_platformGlContext != static_cast<QOpenKODEIntegration *>(QApplicationPrivate::platformIntegration())) {
+ delete m_platformGlContext;
+ }
+ if (m_kdWindow)
+ kdDestroyWindow(m_kdWindow);
+}
+void QOpenKODEWindow::setGeometry(const QRect &rect)
+{
+ if (isFullScreen) {
+ QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens();
+ QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0));
+ widget()->setGeometry(screen->geometry());
+ return;
+ }
+ bool needToDeleteContext = false;
+ if (!isFullScreen) {
+ const QRect geo = geometry();
+ if (geo.size() != rect.size()) {
+ const KDint windowSize[2] = { rect.width(), rect.height() };
+ if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_SIZE, windowSize)) {
+ qErrnoWarning(kdGetError(), "Could not set native window size");
+ //return;
+ } else {
+ needToDeleteContext = true;
+ }
+ }
+
+ if (geo.topLeft() != rect.topLeft()) {
+ const KDint windowPos[2] = { rect.x(), rect.y() };
+ if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_DESKTOP_OFFSET_NV, windowPos)) {
+ qErrnoWarning(kdGetError(), "Could not set native window position");
+ //return;
+ } else {
+ needToDeleteContext = true;
+ }
+ }
+ }
+
+ //need to recreate context
+ if (needToDeleteContext) {
+ delete m_platformGlContext;
+
+ QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens();
+ QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0));
+ EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData());
+ m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(),m_eglConfig,
+ m_eglContextAttrs.data(),surface,m_eglApi);
+ }
+}
+
+void QOpenKODEWindow::setVisible(bool visible)
+{
+ if (!m_kdWindow)
+ return;
+ KDboolean visibillity(visible);
+ if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visibillity)) {
+ qErrnoWarning(kdGetError(), "Could not set visibillity property");
+ }
+}
+
+WId QOpenKODEWindow::winId() const
+{
+ static int i = 0;
+ return i++;
+}
+
+QPlatformGLContext *QOpenKODEWindow::glContext() const
+{
+ return m_platformGlContext;
+}
+
+void QOpenKODEWindow::raise()
+{
+ if (!m_kdWindow)
+ return;
+ KDboolean focus(true);
+ if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_FOCUS, &focus)) {
+ qErrnoWarning(kdGetError(), "Could not set focus");
+ }
+}
+
+void QOpenKODEWindow::lower()
+{
+ if (!m_kdWindow)
+ return;
+ KDboolean focus(false);
+ if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_FOCUS, &focus)) {
+ qErrnoWarning(kdGetError(), "Could not set focus");
+ }
+}
+
+void QOpenKODEWindow::processMouseEvents(const KDEvent *event)
+{
+ int x = event->data.inputpointer.x;
+ int y = event->data.inputpointer.y;
+ Qt::MouseButtons buttons;
+ switch(event->data.inputpointer.select) {
+ case 1:
+ buttons = Qt::LeftButton;
+ break;
+ default:
+ buttons = Qt::NoButton;
+ }
+ QPoint pos(x,y);
+ QWindowSystemInterface::handleMouseEvent(0,event->timestamp,pos,pos,buttons);
+}
+
+void QOpenKODEWindow::processKeyEvents(const KDEvent *event)
+{
+#ifdef KD_ATX_keyboard
+ //KD_KEY_PRESS_ATX 1
+ QEvent::Type keyPressed = QEvent::KeyRelease;
+ if (event->data.keyboardInputKey.flags)
+ keyPressed = QEvent::KeyPress;
+//KD_KEY_LOCATION_LEFT_ATX // dont care for now
+//KD_KEY_LOCATION_RIGHT_ATX
+//KD_KEY_LOCATION_NUMPAD_ATX
+ Qt::KeyboardModifiers mod = Qt::NoModifier;
+ int openkodeMods = event->data.keyboardInputKey.flags;
+ if (openkodeMods & KD_KEY_MODIFIER_SHIFT_ATX)
+ mod |= Qt::ShiftModifier;
+ if (openkodeMods & KD_KEY_MODIFIER_CTRL_ATX)
+ mod |= Qt::ControlModifier;
+ if (openkodeMods & KD_KEY_MODIFIER_ALT_ATX)
+ mod |= Qt::AltModifier;
+ if (openkodeMods & KD_KEY_MODIFIER_META_ATX)
+ mod |= Qt::MetaModifier;
+
+ Qt::Key qtKey;
+ QChar keyText;
+ int key = event->data.keyboardInputKey.keycode;
+ if (key >= 0x20 && key <= 0x0ff){ // 8 bit printable Latin1
+ qtKey = Qt::Key(key);
+ keyText = QChar(event->data.keyboardInputKeyChar.character);
+ if (!(mod & Qt::ShiftModifier))
+ keyText = keyText.toLower();
+ } else {
+ qtKey = keyTranslator(key);
+ }
+ QWindowSystemInterface::handleKeyEvent(0,event->timestamp,keyPressed,qtKey,mod,keyText);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.h b/src/plugins/platforms/openkode/qopenkodewindow.h
new file mode 100644
index 0000000000..83b04b410b
--- /dev/null
+++ b/src/plugins/platforms/openkode/qopenkodewindow.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$
+** 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 QOPENKODEWINDOW_H
+#define QOPENKODEWINDOW_H
+
+#include <QtGui/QPlatformWindow>
+#include <QtCore/QVector>
+
+#include <KD/kd.h>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+class QEGLPlatformContext;
+class QPlatformEventLoopIntegration;
+
+class QOpenKODEWindow : public QPlatformWindow
+{
+public:
+ QOpenKODEWindow(QWidget *tlw);
+ ~QOpenKODEWindow();
+
+ void setGeometry(const QRect &rect);
+ void setVisible(bool visible);
+ WId winId() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void raise();
+ void lower();
+
+ void processKeyEvents( const KDEvent *event );
+ void processMouseEvents( const KDEvent *event );
+
+private:
+ struct KDWindow *m_kdWindow;
+ EGLNativeWindowType m_eglWindow;
+ EGLConfig m_eglConfig;
+ QVector<EGLint> m_eglWindowAttrs;
+ QVector<EGLint> m_eglContextAttrs;
+ EGLenum m_eglApi;
+ QEGLPlatformContext *m_platformGlContext;
+
+ bool isFullScreen;
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif //QOPENKODEWINDOW_H
diff --git a/src/plugins/platforms/openkode/resources.qrc b/src/plugins/platforms/openkode/resources.qrc
new file mode 100644
index 0000000000..dbb34199ff
--- /dev/null
+++ b/src/plugins/platforms/openkode/resources.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>shaders/vert.glslv</file>
+ <file>shaders/frag.glslf</file>
+</qresource>
+</RCC>
diff --git a/src/plugins/platforms/openkode/shaders/frag.glslf b/src/plugins/platforms/openkode/shaders/frag.glslf
new file mode 100644
index 0000000000..ceac785149
--- /dev/null
+++ b/src/plugins/platforms/openkode/shaders/frag.glslf
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+uniform sampler2D tex_samp;
+
+varying vec2 texcoord_var;
+
+void main(void)
+{
+ gl_FragColor = texture2D(tex_samp, texcoord_var);
+}
diff --git a/src/plugins/platforms/openkode/shaders/vert.glslv b/src/plugins/platforms/openkode/shaders/vert.glslv
new file mode 100644
index 0000000000..cc409857bd
--- /dev/null
+++ b/src/plugins/platforms/openkode/shaders/vert.glslv
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+uniform vec2 window; // window size
+
+// Per-vertex attributes]
+attribute vec2 pos_attr;
+attribute vec2 texcoord_attr;
+
+// Output vertex color
+varying vec2 texcoord_var;
+
+void main()
+{
+ gl_Position = vec4( (2.0 * pos_attr / window -1.0) * vec2(1.0, -1.0), 0.0, 1.0);
+ texcoord_var = texcoord_attr;
+}
diff --git a/src/plugins/platforms/openvglite/main.cpp b/src/plugins/platforms/openvglite/main.cpp
new file mode 100644
index 0000000000..97321fa945
--- /dev/null
+++ b/src/plugins/platforms/openvglite/main.cpp
@@ -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$
+** 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 <private/qgraphicssystemplugin_p.h>
+#include "qgraphicssystem_vglite.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVGGraphicsSystemPlugin : public QGraphicsSystemPlugin
+{
+public:
+ QStringList keys() const;
+ QGraphicsSystem *create(const QString&);
+};
+
+QStringList QVGGraphicsSystemPlugin::keys() const
+{
+ QStringList list;
+ list << "OpenVG";
+ return list;
+}
+
+QGraphicsSystem* QVGGraphicsSystemPlugin::create(const QString& system)
+{
+ if (system.toLower() == "openvg")
+ return new QVGLiteGraphicsSystem;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(openvg, QVGGraphicsSystemPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openvglite/openvglite.pro b/src/plugins/platforms/openvglite/openvglite.pro
new file mode 100644
index 0000000000..9d7860abe7
--- /dev/null
+++ b/src/plugins/platforms/openvglite/openvglite.pro
@@ -0,0 +1,12 @@
+TARGET = qvglitegraphicssystem
+include(../../qpluginbase.pri)
+
+QT += openvg
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems
+
+SOURCES = main.cpp qgraphicssystem_vglite.cpp qwindowsurface_vglite.cpp
+HEADERS = qgraphicssystem_vglite.h qwindowsurface_vglite.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
+INSTALLS += target
diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
new file mode 100644
index 0000000000..5f7106e616
--- /dev/null
+++ b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** 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 "qgraphicssystem_vglite.h"
+#include "qwindowsurface_vglite.h"
+#include <QtOpenVG/private/qpixmapdata_vg_p.h>
+#include <QtGui/private/qegl_p.h>
+#include <QtCore/qdebug.h>
+#ifdef OPENVG_USBHP_INIT
+extern "C" {
+#include <linuxusbhp.h>
+};
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QVGLiteGraphicsSystem::QVGLiteGraphicsSystem()
+ : w(0), h(0), d(0), dw(0), dh(0), physWidth(0), physHeight(0),
+ surface(0), context(0), rootWindow(0),
+ screenFormat(QImage::Format_RGB16), preservedSwap(false)
+{
+#ifdef OPENVG_USBHP_INIT
+ initLibrary();
+#endif
+
+ // The graphics system is also the screen definition.
+ mScreens.append(this);
+
+ QString displaySpec = QString::fromLatin1(qgetenv("QWS_DISPLAY"));
+ QStringList displayArgs = displaySpec.split(QLatin1Char(':'));
+
+ // Initialize EGL and create the global EGL context.
+ context = qt_vg_create_context(0);
+ if (!context) {
+ qFatal("QVGLiteGraphicsSystem: could not initialize EGL");
+ return;
+ }
+
+ // Get the root window handle to use. Default to zero.
+ QRegExp winidRx(QLatin1String("winid=?(\\d+)"));
+ int winidIdx = displayArgs.indexOf(winidRx);
+ int handle = 0;
+ if (winidIdx >= 0) {
+ winidRx.exactMatch(displayArgs.at(winidIdx));
+ handle = winidRx.cap(1).toInt();
+ }
+
+ // Create a full-screen window based on the native handle.
+ // If the context is premultiplied, the window should be too.
+ QEglProperties props;
+#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
+ EGLint surfaceType = 0;
+ if (context->configAttrib(EGL_SURFACE_TYPE, &surfaceType) &&
+ (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0)
+ props.setValue(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE);
+#endif
+ rootWindow = eglCreateWindowSurface
+ (context->display(), context->config(),
+ (EGLNativeWindowType)handle, props.properties());
+ if (rootWindow == EGL_NO_SURFACE) {
+ delete context;
+ context = 0;
+ qFatal("QVGLiteGraphicsSystem: could not create full-screen window");
+ return;
+ }
+
+ // Try to turn on preserved swap behaviour on the root window.
+ // This will allow us to optimize compositing to focus on just
+ // the screen region that has changed. Otherwise we must
+ // re-composite the entire screen every frame.
+#if !defined(QVG_NO_PRESERVED_SWAP)
+ eglGetError(); // Clear error state first.
+ eglSurfaceAttrib(context->display(), rootWindow,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+ preservedSwap = (eglGetError() == EGL_SUCCESS);
+#else
+ preservedSwap = false;
+#endif
+
+ // Fetch the root window properties.
+ eglQuerySurface(context->display(), rootWindow, EGL_WIDTH, &w);
+ eglQuerySurface(context->display(), rootWindow, EGL_HEIGHT, &h);
+ screenFormat = qt_vg_config_to_image_format(context);
+ switch (screenFormat) {
+ case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_ARGB32:
+ case QImage::Format_RGB32:
+ default:
+ d = 32;
+ break;
+ case QImage::Format_RGB16:
+ case QImage::Format_ARGB4444_Premultiplied:
+ d = 16;
+ break;
+ }
+ dw = w;
+ dh = h;
+ qDebug("screen size: %dx%dx%d", w, h, d);
+
+ // Handle display physical size spec. From qscreenlinuxfb_qws.cpp.
+ 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);
+ }
+}
+
+QVGLiteGraphicsSystem::~QVGLiteGraphicsSystem()
+{
+}
+
+QPixmapData *QVGLiteGraphicsSystem::createPixmapData(QPixmapData::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);
+ else
+ return new QRasterPixmapData(type);
+#else
+ return new QRasterPixmapData(type);
+#endif
+}
+
+QWindowSurface *QVGLiteGraphicsSystem::createWindowSurface(QWidget *widget) const
+{
+ if (widget->windowType() == Qt::Desktop)
+ return 0; // Don't create an explicit window surface for the destkop.
+ if (surface) {
+ qWarning() << "QVGLiteGraphicsSystem: only one window surface "
+ "is supported at a time";
+ return 0;
+ }
+ surface = new QVGLiteWindowSurface
+ (const_cast<QVGLiteGraphicsSystem *>(this), widget);
+ return surface;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
new file mode 100644
index 0000000000..9d45bf9dda
--- /dev/null
+++ b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QGRAPHICSSYSTEM_VGLITE_H
+#define QGRAPHICSSYSTEM_VGLITE_H
+
+#include <QtGui/private/qgraphicssystem_p.h>
+#include <QtGui/private/qegl_p.h>
+#include <QtGui/qimage.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVGLiteWindowSurface;
+
+class QVGLiteGraphicsSystem : public QGraphicsSystem,
+ public QGraphicsSystemScreen
+{
+public:
+ QVGLiteGraphicsSystem();
+ ~QVGLiteGraphicsSystem();
+
+ QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QWindowSurface *createWindowSurface(QWidget *widget) const;
+ QList<QGraphicsSystemScreen *> screens() const { return mScreens; }
+
+ QRect geometry() const { return QRect(0, 0, w, h); }
+ int depth() const { return d; }
+ QImage::Format format() const { return screenFormat; }
+ QSize physicalSize() const { return QSize(physWidth, physHeight); }
+
+private:
+ friend class QVGLiteWindowSurface;
+
+ int w;
+ int h;
+ int d;
+
+ int dw;
+ int dh;
+
+ int physWidth;
+ int physHeight;
+
+ mutable QVGLiteWindowSurface *surface;
+ QEglContext *context;
+ EGLSurface rootWindow;
+ QImage::Format screenFormat;
+ bool preservedSwap;
+
+ QList<QGraphicsSystemScreen *> mScreens;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/openvglite/qwindowsurface_vglite.cpp b/src/plugins/platforms/openvglite/qwindowsurface_vglite.cpp
new file mode 100644
index 0000000000..8432ad6af7
--- /dev/null
+++ b/src/plugins/platforms/openvglite/qwindowsurface_vglite.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$
+** 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 "qwindowsurface_vglite.h"
+#include "qgraphicssystem_vglite.h"
+#include <QtOpenVG/qvg.h>
+#include <QtOpenVG/private/qvg_p.h>
+#include <QtOpenVG/private/qpaintengine_vg_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QVGLiteWindowSurface::QVGLiteWindowSurface
+ (QVGLiteGraphicsSystem *gs, QWidget *window)
+ : QWindowSurface(window), graphicsSystem(gs),
+ isPaintingActive(false), engine(0)
+{
+}
+
+QVGLiteWindowSurface::~QVGLiteWindowSurface()
+{
+ graphicsSystem->surface = 0;
+ if (engine)
+ qt_vg_destroy_paint_engine(engine);
+}
+
+QPaintDevice *QVGLiteWindowSurface::paintDevice()
+{
+ qt_vg_make_current(graphicsSystem->context, graphicsSystem->rootWindow);
+ isPaintingActive = true;
+ // TODO: clear the parts of the back buffer that are not
+ // covered by the window surface to black.
+ return this;
+}
+
+void QVGLiteWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+ QEglContext *context = graphicsSystem->context;
+ if (context) {
+ if (!isPaintingActive)
+ qt_vg_make_current(context, graphicsSystem->rootWindow);
+ context->swapBuffers();
+ qt_vg_done_current(context);
+ context->setSurface(EGL_NO_SURFACE);
+ isPaintingActive = false;
+ }
+}
+
+void QVGLiteWindowSurface::setGeometry(const QRect &rect)
+{
+ QWindowSurface::setGeometry(rect);
+}
+
+bool QVGLiteWindowSurface::scroll(const QRegion &area, int dx, int dy)
+{
+ return QWindowSurface::scroll(area, dx, dy);
+}
+
+void QVGLiteWindowSurface::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+}
+
+void QVGLiteWindowSurface::endPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+}
+
+QPaintEngine *QVGLiteWindowSurface::paintEngine() const
+{
+ if (!engine)
+ engine = qt_vg_create_paint_engine();
+ return engine;
+}
+
+// We need to get access to QWidget::metric() from QVGLiteWindowSurface::metric,
+// but it is not a friend of QWidget. To get around this, we create a
+// fake QX11PaintEngine class, which is a friend.
+class QX11PaintEngine
+{
+public:
+ static int metric(const QWidget *widget, QPaintDevice::PaintDeviceMetric met)
+ {
+ return widget->metric(met);
+ }
+};
+
+int QVGLiteWindowSurface::metric(PaintDeviceMetric met) const
+{
+ return QX11PaintEngine::metric(window(), met);
+}
diff --git a/src/plugins/platforms/openvglite/qwindowsurface_vglite.h b/src/plugins/platforms/openvglite/qwindowsurface_vglite.h
new file mode 100644
index 0000000000..6d66c42c49
--- /dev/null
+++ b/src/plugins/platforms/openvglite/qwindowsurface_vglite.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$
+** 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 QWINDOWSURFACE_VGLITE_H
+#define QWINDOWSURFACE_VGLITE_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/private/qwindowsurface_p.h>
+#include <QtGui/private/qegl_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVGLiteGraphicsSystem;
+class QVGPaintEngine;
+
+class Q_OPENVG_EXPORT QVGLiteWindowSurface : public QWindowSurface, public QPaintDevice
+{
+public:
+ QVGLiteWindowSurface(QVGLiteGraphicsSystem *gs, QWidget *window);
+ ~QVGLiteWindowSurface();
+
+ 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;
+
+protected:
+ int metric(PaintDeviceMetric metric) const;
+
+private:
+ QVGLiteGraphicsSystem *graphicsSystem;
+ bool isPaintingActive;
+ mutable QVGPaintEngine *engine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSURFACE_VGLITE_H
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
new file mode 100644
index 0000000000..57015e7924
--- /dev/null
+++ b/src/plugins/platforms/platforms.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+
+SUBDIRS += minimal
+
+contains(QT_CONFIG, wayland) {
+ SUBDIRS += wayland
+}
+
diff --git a/src/plugins/platforms/qvfb/main.cpp b/src/plugins/platforms/qvfb/main.cpp
new file mode 100644
index 0000000000..5c3b72bc7c
--- /dev/null
+++ b/src/plugins/platforms/qvfb/main.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 <QPlatformIntegrationPlugin>
+#include "qvfbintegration.h"
+#include <qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVFbIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QVFbIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "QVFb";
+ return list;
+}
+
+QPlatformIntegration* QVFbIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "qvfb")
+ return new QVFbIntegration(paramList);
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(qvfb, QVFbIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qvfb/qvfb.pro b/src/plugins/platforms/qvfb/qvfb.pro
new file mode 100644
index 0000000000..d2b332a6d5
--- /dev/null
+++ b/src/plugins/platforms/qvfb/qvfb.pro
@@ -0,0 +1,13 @@
+TARGET = qvfbintegration
+include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+
+SOURCES = main.cpp qvfbintegration.cpp qvfbwindowsurface.cpp
+HEADERS = qvfbintegration.h qvfbwindowsurface.h
+
+include(../fontdatabases/genericunix/genericunix.pri)
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.cpp b/src/plugins/platforms/qvfb/qvfbintegration.cpp
new file mode 100644
index 0000000000..ddde8008d2
--- /dev/null
+++ b/src/plugins/platforms/qvfb/qvfbintegration.cpp
@@ -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$
+** 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 <stdlib.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <private/qcore_unix_p.h> // overrides QT_OPEN
+
+#include <qvfbhdr.h>
+#include <qsocketnotifier.h>
+
+#include "qvfbintegration.h"
+#include "qvfbwindowsurface.h"
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtCore/qdebug.h>
+#include <QMouseEvent>
+
+#include <qsocketnotifier.h>
+#include <QApplication>
+#include <QWindowSystemInterface>
+
+#include "qgenericunixfontdatabase.h"
+
+QT_BEGIN_NAMESPACE
+
+
+class QVFbScreenKeyboardHandler : public QObject
+{
+ Q_OBJECT
+public:
+ QVFbScreenKeyboardHandler(int displayId);
+ ~QVFbScreenKeyboardHandler();
+
+private slots:
+ void readKeyboardData();
+
+private:
+ int kbdFD;
+ int kbdIdx;
+ int kbdBufferLen;
+ unsigned char *kbdBuffer;
+ QSocketNotifier *keyNotifier;
+};
+
+QVFbScreenKeyboardHandler::QVFbScreenKeyboardHandler(int displayId)
+{
+ const QString keyboardDev = QT_VFB_KEYBOARD_PIPE(displayId);
+
+
+ kbdFD = -1;
+ kbdIdx = 0;
+ kbdBufferLen = sizeof(QVFbKeyData) * 5;
+ kbdBuffer = new unsigned char [kbdBufferLen];
+
+ kbdFD = QT_OPEN(keyboardDev.toLatin1().constData(), O_RDWR | O_NDELAY);
+
+ if (kbdFD == -1) {
+ perror("QVFbScreenKeyboardHandler");
+ qWarning("QVFbScreenKeyboardHandler: Unable to open device %s",
+ qPrintable(keyboardDev));
+ return;
+ }
+
+ // Clear pending input
+ char buf[2];
+ while (QT_READ(kbdFD, buf, 1) > 0) { }
+
+ keyNotifier = new QSocketNotifier(kbdFD, QSocketNotifier::Read, this);
+ connect(keyNotifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData()));
+
+}
+
+QVFbScreenKeyboardHandler::~QVFbScreenKeyboardHandler()
+{
+ if (kbdFD >= 0)
+ QT_CLOSE(kbdFD);
+ delete [] kbdBuffer;
+}
+
+
+void QVFbScreenKeyboardHandler::readKeyboardData()
+{
+ int n;
+ do {
+ n = QT_READ(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx);
+ if (n > 0)
+ kbdIdx += n;
+ } while (n > 0);
+
+ int idx = 0;
+ while (kbdIdx - idx >= (int)sizeof(QVFbKeyData)) {
+ QVFbKeyData *kd = (QVFbKeyData *)(kbdBuffer + idx);
+ if (kd->unicode == 0 && kd->keycode == 0 && kd->modifiers == 0 && kd->press) {
+ // magic exit key
+ qWarning("Instructed to quit by Virtual Keyboard");
+ qApp->quit();
+ }
+
+ //QWSServer::processKeyEvent(kd->unicode ? kd->unicode : 0xffff, kd->keycode, kd->modifiers, kd->press, kd->repeat);
+
+ QEvent::Type type = kd->press ? QEvent::KeyPress : QEvent::KeyRelease;
+
+ QString text;
+ if (kd->unicode && kd->unicode != 0xffff)
+ text += QChar(kd->unicode);
+
+// qDebug() << "readKeyboardData" << type << hex << kd->keycode << kd->modifiers << text;
+
+ QWindowSystemInterface::handleKeyEvent(0, type, kd->keycode, kd->modifiers, text, kd->repeat, int(text.length()));
+ idx += sizeof(QVFbKeyData);
+ }
+
+ int surplus = kbdIdx - idx;
+ for (int i = 0; i < surplus; i++)
+ kbdBuffer[i] = kbdBuffer[idx+i];
+ kbdIdx = surplus;
+}
+
+
+
+
+class QVFbScreenMouseHandler : public QObject
+{
+ Q_OBJECT
+public:
+ QVFbScreenMouseHandler(int displayId);
+ ~QVFbScreenMouseHandler();
+
+private slots:
+ void readMouseData();
+
+private:
+ int mouseFD;
+ int mouseIdx;
+ enum {mouseBufSize = 128};
+ uchar mouseBuf[mouseBufSize];
+ QSocketNotifier *mouseNotifier;
+
+ int oldButtonState;
+};
+
+QVFbScreenMouseHandler::QVFbScreenMouseHandler(int displayId)
+{
+ QString mouseDev = QT_VFB_MOUSE_PIPE(displayId);
+
+ mouseFD = QT_OPEN(mouseDev.toLatin1().constData(), O_RDWR | O_NDELAY);
+
+ if (mouseFD == -1) {
+ perror("QVFbMouseHandler::QVFbMouseHandler");
+ qWarning("QVFbMouseHander: Unable to open device %s",
+ qPrintable(mouseDev));
+ return;
+ }
+
+ // Clear pending input
+ char buf[2];
+ while (QT_READ(mouseFD, buf, 1) > 0) { }
+
+ mouseIdx = 0;
+ oldButtonState = 0;
+ mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
+ connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
+}
+
+
+QVFbScreenMouseHandler::~QVFbScreenMouseHandler()
+{
+ if (mouseFD >= 0)
+ QT_CLOSE(mouseFD);
+}
+
+void QVFbScreenMouseHandler::readMouseData()
+{
+ int n;
+ do {
+ n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx);
+ if (n > 0)
+ mouseIdx += n;
+ } while (n > 0);
+
+ int idx = 0;
+ static const int packetsize = sizeof(QPoint) + 2*sizeof(int);
+ while (mouseIdx-idx >= packetsize) {
+ uchar *mb = mouseBuf+idx;
+ QPoint mousePos = *reinterpret_cast<QPoint *>(mb);
+ mb += sizeof(QPoint);
+ int bstate = *reinterpret_cast<int *>(mb);
+ mb += sizeof(int);
+ //int wheel = *reinterpret_cast<int *>(mb);
+
+ int button = bstate ^ oldButtonState;
+ QEvent::Type type = QEvent::MouseMove;
+
+ if (button) {
+ type = (button & bstate) ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
+ }
+ QWindowSystemInterface::handleMouseEvent(0, mousePos, mousePos, Qt::MouseButtons(bstate));
+
+// qDebug() << "readMouseData" << mousePos << button << bstate << oldButtonState << type;
+
+ oldButtonState = bstate;
+
+ idx += packetsize;
+ }
+
+ int surplus = mouseIdx - idx;
+ for (int i = 0; i < surplus; i++)
+ mouseBuf[i] = mouseBuf[idx+i];
+ mouseIdx = surplus;
+
+}
+
+
+class QVFbScreenPrivate
+{
+public:
+ QVFbScreenPrivate(int id)
+ : shmrgn(0), hdr(0), data(0), mouseHandler(0), keyboardHandler(0)
+ {
+ displayId = id;
+ connect(displayId);
+ }
+
+ ~QVFbScreenPrivate() { disconnect(); }
+ void setDirty(const QRect &r);
+
+ bool connect(int displayId);
+ void disconnect();
+
+ QImage *screenImage() { return &img; }
+ QSize screenSize() { return img.size(); }
+
+ int depth() const { return img.depth(); }
+ QImage::Format format() const { return img.format(); }
+
+private:
+ unsigned char *shmrgn;
+ QVFbHeader *hdr;
+ uchar *data;
+ QVFbScreenMouseHandler *mouseHandler;
+ QVFbScreenKeyboardHandler *keyboardHandler;
+ int displayId;
+
+ QImage img;
+};
+
+
+void QVFbScreenPrivate::setDirty(const QRect &r)
+{
+ hdr->dirty = true;
+ hdr->update = hdr->update.united(r);
+}
+
+
+bool QVFbScreenPrivate::connect(int displayId)
+{
+ qDebug() << "QVFbScreenPrivate::connect" << displayId;
+ key_t key = ftok(QT_VFB_MOUSE_PIPE(displayId).toLatin1(), 'b');
+
+ if (key == -1)
+ return false;
+
+
+ int shmId = shmget(key, 0, 0);
+ if (shmId != -1)
+ shmrgn = (unsigned char *)shmat(shmId, 0, 0);
+ else
+ return false;
+
+ if ((long)shmrgn == -1 || shmrgn == 0) {
+ qDebug("No shmrgn %ld", (long)shmrgn);
+ return false;
+ }
+
+ hdr = (QVFbHeader *)shmrgn;
+ data = shmrgn + hdr->dataoffset;
+
+ int w = hdr->width;
+ int h = hdr->height;
+ int d = hdr->depth;
+ int lstep = hdr->linestep;
+
+ QImage::Format format = QImage::Format_Invalid;
+ if (d == 32)
+ format = QImage::Format_ARGB32_Premultiplied;
+ else if (d == 16)
+ format = QImage::Format_RGB16;
+
+
+ if (format == QImage::Format_Invalid) {
+ img = QImage();
+ return false;
+ }
+
+ img = QImage(data, w, h, lstep, format);
+
+ qDebug("connected %dx%d %d bpp", w, h, d);
+
+
+ mouseHandler = new QVFbScreenMouseHandler(displayId);
+ keyboardHandler = new QVFbScreenKeyboardHandler(displayId);
+ return true;
+}
+
+void QVFbScreenPrivate::disconnect()
+{
+ if ((long)shmrgn != -1 && shmrgn) {
+ shmdt((char*)shmrgn);
+ shmrgn = 0;
+ }
+ delete mouseHandler;
+ mouseHandler = 0;
+ delete keyboardHandler;
+ keyboardHandler = 0;
+}
+
+
+QVFbScreen::QVFbScreen(int id)
+{
+ d_ptr = new QVFbScreenPrivate(id);
+}
+
+
+QVFbScreen::~QVFbScreen()
+{
+ delete d_ptr;
+}
+
+void QVFbScreen::setDirty(const QRect &rect)
+{
+ d_ptr->setDirty(rect);
+}
+
+
+
+QRect QVFbScreen::geometry() const {
+ return QRect(QPoint(), d_ptr->screenSize());
+}
+
+
+int QVFbScreen::depth() const
+{
+ return d_ptr->depth();
+}
+
+QImage::Format QVFbScreen::format() const
+{
+ return d_ptr->format();
+}
+
+QSize QVFbScreen::physicalSize() const {
+ return (d_ptr->screenSize()*254)/720;
+}
+
+#if 0
+int QVFbScreen::linestep() const {
+ return d_ptr->screenImage() ? d_ptr->screenImage()->bytesPerLine() : 0;
+}
+
+uchar *QVFbScreen::base() const {
+ return d_ptr->screenImage() ? d_ptr->screenImage()->bits() : 0;
+}
+#endif
+
+QImage *QVFbScreen::screenImage()
+{
+ return d_ptr->screenImage();
+}
+
+QVFbIntegration::QVFbIntegration(const QStringList &paramList)
+ : mFontDb(new QGenericUnixFontDatabase())
+{
+ int displayId = 0;
+ if (paramList.length() > 0)
+ displayId = paramList.at(0).toInt();
+
+ mPrimaryScreen = new QVFbScreen(displayId);
+
+ mScreens.append(mPrimaryScreen);
+}
+
+QPixmapData *QVFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QWindowSurface *QVFbIntegration::createWindowSurface(QWidget *widget, WId) const
+{
+ return new QVFbWindowSurface(mPrimaryScreen, widget);
+}
+
+
+QPlatformWindow *QVFbIntegration::createPlatformWindow(QWidget *widget, WId) const
+{
+ return new QVFbWindow(mPrimaryScreen, widget);
+}
+
+QPlatformFontDatabase *QVFbIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
+QT_END_NAMESPACE
+
+#include "qvfbintegration.moc"
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.h b/src/plugins/platforms/qvfb/qvfbintegration.h
new file mode 100644
index 0000000000..33e31a5aaa
--- /dev/null
+++ b/src/plugins/platforms/qvfb/qvfbintegration.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** 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 QGRAPHICSSYSTEM_QVFB_H
+#define QGRAPHICSSYSTEM_QVFB_H
+
+#include <QPlatformScreen>
+#include <QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+
+class QVFbScreenPrivate;
+
+class QVFbScreen : public QPlatformScreen
+{
+public:
+ QVFbScreen(int id);
+ ~QVFbScreen();
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSize physicalSize() const;
+
+ QImage *screenImage();
+
+ void setDirty(const QRect &rect);
+
+public:
+
+ QVFbScreenPrivate *d_ptr;
+};
+
+class QVFbIntegrationPrivate;
+
+
+class QVFbIntegration : public QPlatformIntegration
+{
+public:
+ QVFbIntegration(const QStringList &paramList);
+
+ 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; }
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+private:
+ QVFbScreen *mPrimaryScreen;
+ QList<QPlatformScreen *> mScreens;
+ QPlatformFontDatabase *mFontDb;
+};
+
+
+
+QT_END_NAMESPACE
+
+
+#endif
diff --git a/src/plugins/platforms/qvfb/qvfbwindowsurface.cpp b/src/plugins/platforms/qvfb/qvfbwindowsurface.cpp
new file mode 100644
index 0000000000..85918eb1bb
--- /dev/null
+++ b/src/plugins/platforms/qvfb/qvfbwindowsurface.cpp
@@ -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$
+**
+****************************************************************************/
+
+
+#include "qvfbwindowsurface.h"
+#include "qvfbintegration.h"
+#include <QtCore/qdebug.h>
+#include <QtGui/qpainter.h>
+#include <private/qapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QVFbWindowSurface::QVFbWindowSurface(//QVFbIntegration *graphicsSystem,
+ QVFbScreen *screen, QWidget *window)
+ : QWindowSurface(window),
+ mScreen(screen)
+{
+}
+
+QVFbWindowSurface::~QVFbWindowSurface()
+{
+}
+
+QPaintDevice *QVFbWindowSurface::paintDevice()
+{
+ return mScreen->screenImage();
+}
+
+void QVFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(offset);
+
+// QRect rect = geometry();
+// QPoint topLeft = rect.topLeft();
+
+ mScreen->setDirty(region.boundingRect());
+}
+
+void QVFbWindowSurface::resize(const QSize&)
+{
+
+// any size you like as long as it's full-screen...
+
+ QRect rect(mScreen->availableGeometry());
+ QWindowSurface::resize(rect.size());
+}
+
+
+QVFbWindow::QVFbWindow(QVFbScreen *screen, QWidget *window)
+ : QPlatformWindow(window),
+ mScreen(screen)
+{
+}
+
+
+void QVFbWindow::setGeometry(const QRect &)
+{
+
+// any size you like as long as it's full-screen...
+
+ QRect rect(mScreen->availableGeometry());
+ QWindowSystemInterface::handleGeometryChange(this->widget(), rect);
+
+ QPlatformWindow::setGeometry(rect);
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qvfb/qvfbwindowsurface.h b/src/plugins/platforms/qvfb/qvfbwindowsurface.h
new file mode 100644
index 0000000000..9f828d3b0f
--- /dev/null
+++ b/src/plugins/platforms/qvfb/qvfbwindowsurface.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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 QWINDOWSURFACE_QVFB_H
+#define QWINDOWSURFACE_QVFB_H
+
+#include <QtGui/private/qwindowsurface_p.h>
+#include <QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QVFbIntegration;
+class QVFbScreen;
+
+class QVFbWindowSurface : public QWindowSurface
+{
+public:
+ QVFbWindowSurface(QVFbScreen *screen, QWidget *window);
+ ~QVFbWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size);
+
+private:
+ QVFbScreen *mScreen;
+};
+
+class QVFbWindow : public QPlatformWindow
+{
+public:
+ QVFbWindow(QVFbScreen *screen, QWidget *window);
+ void setGeometry(const QRect &rect);
+
+private:
+ QVFbScreen *mScreen;
+};
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/uikit/README b/src/plugins/platforms/uikit/README
new file mode 100644
index 0000000000..a101a3ac0b
--- /dev/null
+++ b/src/plugins/platforms/uikit/README
@@ -0,0 +1,45 @@
+This is a proof-of-concept implemenation of a UIKit based
+QPA plugin. Note that this is completely unsupported, and it is probable
+that many parts of QtCore and other Qt Modules don't work properly.
+
+1) Build Qt
+
+The example Xcode project in the examples subdirectory requires that you do shadow
+builds of Qt in qt-lighthouse-ios-simulator and qt-lighthouse-ios-device directories
+parallel to the sources. To build for simulator make sure that both the Simulator
+configuration *and* the simulator specific target are active. To build for device
+make sure that both the Device configuration *and* the device specific target are
+active.
+
+The setup is configured to use the iOS 4.2 SDKs, you might want to edit the mkspecs
+to fit your need.
+
+After configuring and building Qt you need to also build src/plugins/platforms/uikit.
+
+Simulator:
+----------
+configure -qpa -xplatform qws/macx-iphonesimulator-g++ -arch i386 -developer-build -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
+
+Device:
+-------
+configure -qpa -xplatform qws/macx-iphonedevice-g++ -arch armv7 -developer-build -release -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
+
+2) XCode setup:
+- there are examples in the examples subdirectory of the platform plugin
+- to create something fresh do something like:
+ - Xcode: Create a "View-based Appplication"
+ - remove the nibs and view controller and app controller files
+ - remove the reference to "Main nib file" from plist file
+ - create a main.mm like in the examples
+ - add the qmlapplicationviewer sources to your project (including the moc_*.h)
+ (best to link, not copy), the code for this is from the Qt Creator
+ mobile Qt Quick application template
+ - Add the Qt .a libraries, uikit platform plugin and libz (v1.2.3) to Frameworks
+ - add "$(SRCROOT)/../../../../qt-lighthouse-ios-device/include" (or -simulator)
+ to the include search paths.
+ - add "$(SRCROOT)/../qmltest" to the include search path if you didn't copy but
+ linked to the qmlapplicationviewer
+ - for device set the architecture to armv7 only
+
+3) Done: Build and Run.
+
diff --git a/src/plugins/platforms/uikit/examples/qmltest/main.mm b/src/plugins/platforms/uikit/examples/qmltest/main.mm
new file mode 100644
index 0000000000..ea4e90cbee
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/main.mm
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#include "qmlapplicationviewer/qmlapplicationviewer.h"
+
+#include <QtGui/QApplication>
+#include <QtCore/QtPlugin>
+#include <QtDeclarative/QDeclarativeEngine>
+
+Q_IMPORT_PLUGIN(UIKit)
+
+static QString qStringFromNSString(NSString *nsstring)
+{
+ return QString::fromUtf8([nsstring UTF8String]);
+}
+
+static QString documentsDirectory()
+{
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ return qStringFromNSString(documentsDirectory);
+}
+
+int main(int argc, char *argv[]) {
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ QApplication app(argc, argv);
+ QmlApplicationViewer viewer;
+ viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
+ viewer.engine()->setOfflineStoragePath(documentsDirectory());
+ NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
+ viewer.setMainQmlFile(qStringFromNSString([resourcePath stringByAppendingPathComponent:@"qml/main.qml"]));
+ viewer.showMaximized();
+ int retVal = app.exec();
+ [pool release];
+ return retVal;
+}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qml/main.qml b/src/plugins/platforms/uikit/examples/qmltest/qml/main.qml
new file mode 100644
index 0000000000..889a6d063f
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/qml/main.qml
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "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 Nokia Corporation and its Subsidiary(-ies) 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."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+Rectangle {
+ id: box
+ width: 350; height: 250
+
+ Rectangle {
+ id: redSquare
+ width: 80; height: 80
+ anchors.top: parent.top; anchors.left: parent.left; anchors.margins: 10
+ color: "red"
+
+ Text { text: "Click"; font.pixelSize: 16; anchors.centerIn: parent }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+ onEntered: info.text = 'Entered'
+ onExited: info.text = 'Exited (pressed=' + pressed + ')'
+
+ onPressed: {
+ info.text = 'Pressed (button=' + (mouse.button == Qt.RightButton ? 'right' : 'left')
+ + ' shift=' + (mouse.modifiers & Qt.ShiftModifier ? 'true' : 'false') + ')'
+ var posInBox = redSquare.mapToItem(box, mouse.x, mouse.y)
+ posInfo.text = + mouse.x + ',' + mouse.y + ' in square'
+ + ' (' + posInBox.x + ',' + posInBox.y + ' in window)'
+ }
+
+ onReleased: {
+ info.text = 'Released (isClick=' + mouse.isClick + ' wasHeld=' + mouse.wasHeld + ')'
+ posInfo.text = ''
+ }
+
+ onPressAndHold: info.text = 'Press and hold'
+ onClicked: info.text = 'Clicked (wasHeld=' + mouse.wasHeld + ')'
+ onDoubleClicked: info.text = 'Double clicked'
+ }
+ }
+
+ Rectangle {
+ id: blueSquare
+ width: 80; height: 80
+ x: box.width - width - 10; y: 10 // making this item draggable, so don't use anchors
+ color: "blue"
+
+ Text { text: "Drag"; font.pixelSize: 16; color: "white"; anchors.centerIn: parent }
+
+ MouseArea {
+ anchors.fill: parent
+ drag.target: blueSquare
+ drag.axis: Drag.XandYAxis
+ drag.minimumX: 0
+ drag.maximumX: box.width - parent.width
+ drag.minimumY: 0
+ drag.maximumY: box.height - parent.width
+ }
+ }
+
+ Text {
+ id: info
+ anchors.bottom: posInfo.top; anchors.horizontalCenter: parent.horizontalCenter; anchors.margins: 30
+
+ onTextChanged: console.log(text)
+ }
+
+ Text {
+ id: posInfo
+ anchors.bottom: parent.bottom; anchors.horizontalCenter: parent.horizontalCenter; anchors.margins: 30
+ }
+}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp
new file mode 100644
index 0000000000..a2b40ec44a
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/****************************************************************************
+** Meta object code from reading C++ file 'qmlapplicationviewer.h'
+**
+** Created: Fri Feb 18 17:53:42 2011
+** by: The Qt Meta Object Compiler version 62 (Qt 4.7.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "qmlapplicationviewer.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'qmlapplicationviewer.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 62
+#error "This file was generated using the moc from 4.7.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_QmlApplicationViewer[] = {
+
+ // content:
+ 5, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 0, 0, // methods
+ 0, 0, // properties
+ 0, 0, // enums/sets
+ 0, 0, // constructors
+ 0, // flags
+ 0, // signalCount
+
+ 0 // eod
+};
+
+static const char qt_meta_stringdata_QmlApplicationViewer[] = {
+ "QmlApplicationViewer\0"
+};
+
+const QMetaObject QmlApplicationViewer::staticMetaObject = {
+ { &QDeclarativeView::staticMetaObject, qt_meta_stringdata_QmlApplicationViewer,
+ qt_meta_data_QmlApplicationViewer, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &QmlApplicationViewer::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *QmlApplicationViewer::metaObject() const
+{
+ return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *QmlApplicationViewer::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_QmlApplicationViewer))
+ return static_cast<void*>(const_cast< QmlApplicationViewer*>(this));
+ return QDeclarativeView::qt_metacast(_clname);
+}
+
+int QmlApplicationViewer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QDeclarativeView::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ return _id;
+}
+QT_END_MOC_NAMESPACE
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp
new file mode 100644
index 0000000000..72f8c52e7b
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+// checksum 0x17fa version 0x3000a
+/*
+ This file was generated by the Qt Quick Application wizard of Qt Creator.
+ QmlApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#include "qmlapplicationviewer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtDeclarative/QDeclarativeComponent>
+#include <QtDeclarative/QDeclarativeEngine>
+#include <QtDeclarative/QDeclarativeContext>
+
+#if defined(QMLJSDEBUGGER)
+#include <qt_private/qdeclarativedebughelper_p.h>
+#endif
+
+#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
+#include <jsdebuggeragent.h>
+#endif
+#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
+#include <qdeclarativeviewobserver.h>
+#endif
+
+#if defined(QMLJSDEBUGGER)
+
+// Enable debugging before any QDeclarativeEngine is created
+struct QmlJsDebuggingEnabler
+{
+ QmlJsDebuggingEnabler()
+ {
+ QDeclarativeDebugHelper::enableDebugging();
+ }
+};
+
+// Execute code in constructor before first QDeclarativeEngine is instantiated
+static QmlJsDebuggingEnabler enableDebuggingHelper;
+
+#endif // QMLJSDEBUGGER
+
+class QmlApplicationViewerPrivate
+{
+ QString mainQmlFile;
+ friend class QmlApplicationViewer;
+ static QString adjustPath(const QString &path);
+};
+
+QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#ifdef Q_OS_UNIX
+#ifdef Q_OS_MAC
+ if (!QDir::isAbsolutePath(path))
+ return QCoreApplication::applicationDirPath()
+ + QLatin1String("/../Resources/") + path;
+#else
+ const QString pathInShareDir = QCoreApplication::applicationDirPath()
+ + QLatin1String("/../share/")
+ + QFileInfo(QCoreApplication::applicationFilePath()).fileName()
+ + QLatin1Char('/') + path;
+ if (QFileInfo(pathInShareDir).exists())
+ return pathInShareDir;
+#endif
+#endif
+ return path;
+}
+
+QmlApplicationViewer::QmlApplicationViewer(QWidget *parent) :
+ QDeclarativeView(parent),
+ m_d(new QmlApplicationViewerPrivate)
+{
+ connect(engine(), SIGNAL(quit()), SLOT(close()));
+ setResizeMode(QDeclarativeView::SizeRootObjectToView);
+#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
+ new QmlJSDebugger::JSDebuggerAgent(engine());
+#endif
+#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
+ new QmlJSDebugger::QDeclarativeViewObserver(this, parent);
+#endif
+}
+
+QmlApplicationViewer::~QmlApplicationViewer()
+{
+ delete m_d;
+}
+
+void QmlApplicationViewer::setMainQmlFile(const QString &file)
+{
+ m_d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
+ setSource(QUrl::fromLocalFile(m_d->mainQmlFile));
+}
+
+void QmlApplicationViewer::addImportPath(const QString &path)
+{
+ engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path));
+}
+
+void QmlApplicationViewer::setOrientation(ScreenOrientation orientation)
+{
+//#if defined(Q_OS_SYMBIAN)
+// // If the version of Qt on the device is < 4.7.2, that attribute won't work
+// if (orientation != ScreenOrientationAuto) {
+// const QStringList v = QString::fromAscii(qVersion()).split(QLatin1Char('.'));
+// if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
+// qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
+// return;
+// }
+// }
+//#endif // Q_OS_SYMBIAN
+//
+// Qt::WidgetAttribute attribute;
+// switch (orientation) {
+//#if QT_VERSION < 0x040702
+// // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
+// case ScreenOrientationLockPortrait:
+// attribute = static_cast<Qt::WidgetAttribute>(128);
+// break;
+// case ScreenOrientationLockLandscape:
+// attribute = static_cast<Qt::WidgetAttribute>(129);
+// break;
+// default:
+// case ScreenOrientationAuto:
+// attribute = static_cast<Qt::WidgetAttribute>(130);
+// break;
+//#else // QT_VERSION < 0x040702
+// case ScreenOrientationLockPortrait:
+// attribute = Qt::WA_LockPortraitOrientation;
+// break;
+// case ScreenOrientationLockLandscape:
+// attribute = Qt::WA_LockLandscapeOrientation;
+// break;
+// default:
+// case ScreenOrientationAuto:
+// attribute = Qt::WA_AutoOrientation;
+// break;
+//#endif // QT_VERSION < 0x040702
+// };
+// setAttribute(attribute, true);
+}
+
+void QmlApplicationViewer::showExpanded()
+{
+#ifdef Q_OS_SYMBIAN
+ showFullScreen();
+#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
+ showMaximized();
+#else
+ show();
+#endif
+}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h
new file mode 100644
index 0000000000..01b2af0cf9
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+// checksum 0x5a59 version 0x3000a
+/*
+ This file was generated by the Qt Quick Application wizard of Qt Creator.
+ QmlApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#ifndef QMLAPPLICATIONVIEWER_H
+#define QMLAPPLICATIONVIEWER_H
+
+#include <QtDeclarative/QDeclarativeView>
+
+class QmlApplicationViewer : public QDeclarativeView
+{
+ Q_OBJECT
+
+public:
+ enum ScreenOrientation {
+ ScreenOrientationLockPortrait,
+ ScreenOrientationLockLandscape,
+ ScreenOrientationAuto
+ };
+
+ explicit QmlApplicationViewer(QWidget *parent = 0);
+ virtual ~QmlApplicationViewer();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+ void setOrientation(ScreenOrientation orientation);
+ void showExpanded();
+
+private:
+ class QmlApplicationViewerPrivate *m_d;
+};
+
+#endif // QMLAPPLICATIONVIEWER_H
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist b/src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist
new file mode 100644
index 0000000000..15665856b0
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist
@@ -0,0 +1,28 @@
+<?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>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+</dict>
+</plist>
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj b/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj
new file mode 100755
index 0000000000..10bb20fcb9
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj
@@ -0,0 +1,491 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+ 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
+ D316594E1338B29E00760B02 /* libQtXml_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D31659431338B21000760B02 /* libQtXml_debug.a */; };
+ D316594F1338B29E00760B02 /* libQtXmlPatterns_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */; };
+ D35784241345D8C90046D202 /* libQtOpenGL_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784231345D8C90046D202 /* libQtOpenGL_debug.a */; };
+ D35784261345D9940046D202 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784251345D9940046D202 /* OpenGLES.framework */; };
+ D35784281345D9E00046D202 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784271345D9E00046D202 /* QuartzCore.framework */; };
+ D3578436134A09990046D202 /* libQtOpenGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3578435134A09990046D202 /* libQtOpenGL.a */; };
+ D3578439134A0AAE0046D202 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784251345D9940046D202 /* OpenGLES.framework */; };
+ D357843A134A0AB10046D202 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784271345D9E00046D202 /* QuartzCore.framework */; };
+ D3CAA7C813264AAD008BB877 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7C713264AAD008BB877 /* main.mm */; };
+ D3CAA7E613264EA6008BB877 /* moc_qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */; };
+ D3CAA7E713264EA6008BB877 /* qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */; };
+ D3CAA7EC13264F52008BB877 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7C713264AAD008BB877 /* main.mm */; };
+ D3CAA7ED13264F52008BB877 /* moc_qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */; };
+ D3CAA7EE13264F52008BB877 /* qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */; };
+ D3CAA7F013264F52008BB877 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+ D3CAA7F113264F52008BB877 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+ D3CAA7F213264F52008BB877 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
+ D3CAA7FA13264F8A008BB877 /* libz.1.2.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */; };
+ D3CAA81113264FF0008BB877 /* libz.1.2.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */; };
+ D3CAA81B13265056008BB877 /* libQtCore_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81613265056008BB877 /* libQtCore_debug.a */; };
+ D3CAA81C13265056008BB877 /* libQtDeclarative_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81713265056008BB877 /* libQtDeclarative_debug.a */; };
+ D3CAA81D13265056008BB877 /* libQtGui_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81813265056008BB877 /* libQtGui_debug.a */; };
+ D3CAA81E13265056008BB877 /* libQtScript_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81913265056008BB877 /* libQtScript_debug.a */; };
+ D3CAA81F13265056008BB877 /* libQtSql_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81A13265056008BB877 /* libQtSql_debug.a */; };
+ D3CAA8211326507D008BB877 /* libquikit_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA8201326507D008BB877 /* libquikit_debug.a */; };
+ D3CAA82813265220008BB877 /* libQtNetwork_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA82713265220008BB877 /* libQtNetwork_debug.a */; };
+ D3CAA88A132652E5008BB877 /* fonts in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA836132652E5008BB877 /* fonts */; };
+ D3CAA88B132652E5008BB877 /* fonts in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA836132652E5008BB877 /* fonts */; };
+ D3CAA89113265310008BB877 /* qml in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA88E13265310008BB877 /* qml */; };
+ D3CAA89213265310008BB877 /* qml in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA88E13265310008BB877 /* qml */; };
+ D3D817B2132A2CFD00CDE422 /* libQtCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AA132A2CFD00CDE422 /* libQtCore.a */; };
+ D3D817B3132A2CFD00CDE422 /* libQtDeclarative.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AB132A2CFD00CDE422 /* libQtDeclarative.a */; };
+ D3D817B4132A2CFD00CDE422 /* libQtGui.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AC132A2CFD00CDE422 /* libQtGui.a */; };
+ D3D817B5132A2CFD00CDE422 /* libQtNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AD132A2CFD00CDE422 /* libQtNetwork.a */; };
+ D3D817B6132A2CFD00CDE422 /* libQtScript.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AE132A2CFD00CDE422 /* libQtScript.a */; };
+ D3D817B7132A2CFD00CDE422 /* libQtSql.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AF132A2CFD00CDE422 /* libQtSql.a */; };
+ D3D817B8132A2CFD00CDE422 /* libQtXml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817B0132A2CFD00CDE422 /* libQtXml.a */; };
+ D3D817B9132A2CFD00CDE422 /* libQtXmlPatterns.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817B1132A2CFD00CDE422 /* libQtXmlPatterns.a */; };
+ D3D817BB132A2D0E00CDE422 /* libquikit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817BA132A2D0E00CDE422 /* libquikit.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 1D6058910D05DD3D006BFB54 /* qmltest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = qmltest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 32CA4F630368D1EE00C91783 /* qmltest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = qmltest_Prefix.pch; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* qmltest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "qmltest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
+ D31659431338B21000760B02 /* libQtXml_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXml_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtXml_debug.a"; sourceTree = SOURCE_ROOT; };
+ D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXmlPatterns_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtXmlPatterns_debug.a"; sourceTree = SOURCE_ROOT; };
+ D35784231345D8C90046D202 /* libQtOpenGL_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtOpenGL_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtOpenGL_debug.a"; sourceTree = "<group>"; };
+ D35784251345D9940046D202 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+ D35784271345D9E00046D202 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ D3578435134A09990046D202 /* libQtOpenGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtOpenGL.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtOpenGL.a"; sourceTree = "<group>"; };
+ D3CAA7C713264AAD008BB877 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
+ D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_qmlapplicationviewer.cpp; path = qmlapplicationviewer/moc_qmlapplicationviewer.cpp; sourceTree = "<group>"; };
+ D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qmlapplicationviewer.cpp; path = qmlapplicationviewer/qmlapplicationviewer.cpp; sourceTree = "<group>"; };
+ D3CAA7E513264EA6008BB877 /* qmlapplicationviewer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qmlapplicationviewer.h; path = qmlapplicationviewer/qmlapplicationviewer.h; sourceTree = "<group>"; };
+ D3CAA7F613264F52008BB877 /* qmltest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = qmltest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.2.3.dylib; path = usr/lib/libz.1.2.3.dylib; sourceTree = SDKROOT; };
+ D3CAA81613265056008BB877 /* libQtCore_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtCore_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtCore_debug.a"; sourceTree = SOURCE_ROOT; };
+ D3CAA81713265056008BB877 /* libQtDeclarative_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtDeclarative_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtDeclarative_debug.a"; sourceTree = SOURCE_ROOT; };
+ D3CAA81813265056008BB877 /* libQtGui_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtGui_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtGui_debug.a"; sourceTree = SOURCE_ROOT; };
+ D3CAA81913265056008BB877 /* libQtScript_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtScript_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtScript_debug.a"; sourceTree = SOURCE_ROOT; };
+ D3CAA81A13265056008BB877 /* libQtSql_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtSql_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtSql_debug.a"; sourceTree = SOURCE_ROOT; };
+ D3CAA8201326507D008BB877 /* libquikit_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libquikit_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/plugins/platforms/libquikit_debug.a"; sourceTree = SOURCE_ROOT; };
+ D3CAA82713265220008BB877 /* libQtNetwork_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtNetwork_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtNetwork_debug.a"; sourceTree = SOURCE_ROOT; };
+ D3CAA836132652E5008BB877 /* fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; name = fonts; path = ../../../../../../lib/fonts; sourceTree = SOURCE_ROOT; };
+ D3CAA88E13265310008BB877 /* qml */ = {isa = PBXFileReference; lastKnownFileType = folder; path = qml; sourceTree = SOURCE_ROOT; };
+ D3D817AA132A2CFD00CDE422 /* libQtCore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtCore.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtCore.a"; sourceTree = SOURCE_ROOT; };
+ D3D817AB132A2CFD00CDE422 /* libQtDeclarative.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtDeclarative.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtDeclarative.a"; sourceTree = SOURCE_ROOT; };
+ D3D817AC132A2CFD00CDE422 /* libQtGui.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtGui.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtGui.a"; sourceTree = SOURCE_ROOT; };
+ D3D817AD132A2CFD00CDE422 /* libQtNetwork.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtNetwork.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtNetwork.a"; sourceTree = SOURCE_ROOT; };
+ D3D817AE132A2CFD00CDE422 /* libQtScript.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtScript.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtScript.a"; sourceTree = SOURCE_ROOT; };
+ D3D817AF132A2CFD00CDE422 /* libQtSql.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtSql.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtSql.a"; sourceTree = SOURCE_ROOT; };
+ D3D817B0132A2CFD00CDE422 /* libQtXml.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXml.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtXml.a"; sourceTree = SOURCE_ROOT; };
+ D3D817B1132A2CFD00CDE422 /* libQtXmlPatterns.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXmlPatterns.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtXmlPatterns.a"; sourceTree = SOURCE_ROOT; };
+ D3D817BA132A2D0E00CDE422 /* libquikit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libquikit.a; path = "../../../../../../../qt-lighthouse-ios-device/plugins/platforms/libquikit.a"; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D35784281345D9E00046D202 /* QuartzCore.framework in Frameworks */,
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
+ 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
+ D35784261345D9940046D202 /* OpenGLES.framework in Frameworks */,
+ D3CAA7FA13264F8A008BB877 /* libz.1.2.3.dylib in Frameworks */,
+ D3CAA81B13265056008BB877 /* libQtCore_debug.a in Frameworks */,
+ D3CAA81C13265056008BB877 /* libQtDeclarative_debug.a in Frameworks */,
+ D3CAA81D13265056008BB877 /* libQtGui_debug.a in Frameworks */,
+ D3CAA81E13265056008BB877 /* libQtScript_debug.a in Frameworks */,
+ D3CAA81F13265056008BB877 /* libQtSql_debug.a in Frameworks */,
+ D3CAA8211326507D008BB877 /* libquikit_debug.a in Frameworks */,
+ D3CAA82813265220008BB877 /* libQtNetwork_debug.a in Frameworks */,
+ D316594E1338B29E00760B02 /* libQtXml_debug.a in Frameworks */,
+ D316594F1338B29E00760B02 /* libQtXmlPatterns_debug.a in Frameworks */,
+ D35784241345D8C90046D202 /* libQtOpenGL_debug.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D3CAA7EF13264F52008BB877 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D357843A134A0AB10046D202 /* QuartzCore.framework in Frameworks */,
+ D3578439134A0AAE0046D202 /* OpenGLES.framework in Frameworks */,
+ D3CAA7F013264F52008BB877 /* Foundation.framework in Frameworks */,
+ D3CAA7F113264F52008BB877 /* UIKit.framework in Frameworks */,
+ D3CAA7F213264F52008BB877 /* CoreGraphics.framework in Frameworks */,
+ D3CAA81113264FF0008BB877 /* libz.1.2.3.dylib in Frameworks */,
+ D3D817B2132A2CFD00CDE422 /* libQtCore.a in Frameworks */,
+ D3D817B3132A2CFD00CDE422 /* libQtDeclarative.a in Frameworks */,
+ D3D817B4132A2CFD00CDE422 /* libQtGui.a in Frameworks */,
+ D3D817B5132A2CFD00CDE422 /* libQtNetwork.a in Frameworks */,
+ D3D817B6132A2CFD00CDE422 /* libQtScript.a in Frameworks */,
+ D3D817B7132A2CFD00CDE422 /* libQtSql.a in Frameworks */,
+ D3D817B8132A2CFD00CDE422 /* libQtXml.a in Frameworks */,
+ D3D817B9132A2CFD00CDE422 /* libQtXmlPatterns.a in Frameworks */,
+ D3D817BB132A2D0E00CDE422 /* libquikit.a in Frameworks */,
+ D3578436134A09990046D202 /* libQtOpenGL.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1D6058910D05DD3D006BFB54 /* qmltest.app */,
+ D3CAA7F613264F52008BB877 /* qmltest.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ D3CAA7E213264E8C008BB877 /* QMLApplicationViewer */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = CustomTemplate;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 32CA4F630368D1EE00C91783 /* qmltest_Prefix.pch */,
+ D3CAA7C713264AAD008BB877 /* main.mm */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ D3CAA88E13265310008BB877 /* qml */,
+ D3CAA836132652E5008BB877 /* fonts */,
+ 8D1107310486CEB800E47090 /* qmltest-Info.plist */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ D3CAA81513265035008BB877 /* Simulator */,
+ D3CAA8141326500A008BB877 /* Device */,
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
+ 1D30AB110D05D00D00671497 /* Foundation.framework */,
+ 288765A40DF7441C002DB57D /* CoreGraphics.framework */,
+ D35784251345D9940046D202 /* OpenGLES.framework */,
+ D35784271345D9E00046D202 /* QuartzCore.framework */,
+ D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ D3CAA7E213264E8C008BB877 /* QMLApplicationViewer */ = {
+ isa = PBXGroup;
+ children = (
+ D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */,
+ D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */,
+ D3CAA7E513264EA6008BB877 /* qmlapplicationviewer.h */,
+ );
+ name = QMLApplicationViewer;
+ sourceTree = "<group>";
+ };
+ D3CAA8141326500A008BB877 /* Device */ = {
+ isa = PBXGroup;
+ children = (
+ D3D817BA132A2D0E00CDE422 /* libquikit.a */,
+ D3D817AA132A2CFD00CDE422 /* libQtCore.a */,
+ D3D817AB132A2CFD00CDE422 /* libQtDeclarative.a */,
+ D3D817AC132A2CFD00CDE422 /* libQtGui.a */,
+ D3D817AD132A2CFD00CDE422 /* libQtNetwork.a */,
+ D3578435134A09990046D202 /* libQtOpenGL.a */,
+ D3D817AE132A2CFD00CDE422 /* libQtScript.a */,
+ D3D817AF132A2CFD00CDE422 /* libQtSql.a */,
+ D3D817B0132A2CFD00CDE422 /* libQtXml.a */,
+ D3D817B1132A2CFD00CDE422 /* libQtXmlPatterns.a */,
+ );
+ name = Device;
+ sourceTree = "<group>";
+ };
+ D3CAA81513265035008BB877 /* Simulator */ = {
+ isa = PBXGroup;
+ children = (
+ D3CAA8201326507D008BB877 /* libquikit_debug.a */,
+ D3CAA81613265056008BB877 /* libQtCore_debug.a */,
+ D3CAA81713265056008BB877 /* libQtDeclarative_debug.a */,
+ D3CAA81813265056008BB877 /* libQtGui_debug.a */,
+ D3CAA82713265220008BB877 /* libQtNetwork_debug.a */,
+ D35784231345D8C90046D202 /* libQtOpenGL_debug.a */,
+ D3CAA81913265056008BB877 /* libQtScript_debug.a */,
+ D3CAA81A13265056008BB877 /* libQtSql_debug.a */,
+ D31659431338B21000760B02 /* libQtXml_debug.a */,
+ D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */,
+ );
+ name = Simulator;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1D6058900D05DD3D006BFB54 /* qmltest simulator */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "qmltest simulator" */;
+ buildPhases = (
+ 1D60588D0D05DD3D006BFB54 /* Resources */,
+ 1D60588E0D05DD3D006BFB54 /* Sources */,
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "qmltest simulator";
+ productName = qmltest;
+ productReference = 1D6058910D05DD3D006BFB54 /* qmltest.app */;
+ productType = "com.apple.product-type.application";
+ };
+ D3CAA7E813264F52008BB877 /* qmltest device */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D3CAA7F313264F52008BB877 /* Build configuration list for PBXNativeTarget "qmltest device" */;
+ buildPhases = (
+ D3CAA7E913264F52008BB877 /* Resources */,
+ D3CAA7EB13264F52008BB877 /* Sources */,
+ D3CAA7EF13264F52008BB877 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "qmltest device";
+ productName = qmltest;
+ productReference = D3CAA7F613264F52008BB877 /* qmltest.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "qmltest" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 1D6058900D05DD3D006BFB54 /* qmltest simulator */,
+ D3CAA7E813264F52008BB877 /* qmltest device */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1D60588D0D05DD3D006BFB54 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D3CAA88A132652E5008BB877 /* fonts in Resources */,
+ D3CAA89113265310008BB877 /* qml in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D3CAA7E913264F52008BB877 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D3CAA88B132652E5008BB877 /* fonts in Resources */,
+ D3CAA89213265310008BB877 /* qml in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1D60588E0D05DD3D006BFB54 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D3CAA7C813264AAD008BB877 /* main.mm in Sources */,
+ D3CAA7E613264EA6008BB877 /* moc_qmlapplicationviewer.cpp in Sources */,
+ D3CAA7E713264EA6008BB877 /* qmlapplicationviewer.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D3CAA7EB13264F52008BB877 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D3CAA7EC13264F52008BB877 /* main.mm in Sources */,
+ D3CAA7ED13264F52008BB877 /* moc_qmlapplicationviewer.cpp in Sources */,
+ D3CAA7EE13264F52008BB877 /* qmlapplicationviewer.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1D6058940D05DD3E006BFB54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = qmltest_Prefix.pch;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/include\"/**";
+ INFOPLIST_FILE = "qmltest-Info.plist";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/lib\"",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/plugins/platforms\"",
+ );
+ PRODUCT_NAME = qmltest;
+ };
+ name = Debug;
+ };
+ 1D6058950D05DD3E006BFB54 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
+ COPY_PHASE_STRIP = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = qmltest_Prefix.pch;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/include\"/**";
+ INFOPLIST_FILE = "qmltest-Info.plist";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/lib\"",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/plugins/platforms\"",
+ );
+ PRODUCT_NAME = qmltest;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Release;
+ };
+ D3CAA7F413264F52008BB877 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = qmltest_Prefix.pch;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/include\"/**";
+ INFOPLIST_FILE = "qmltest-Info.plist";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/lib\"",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/plugins/platforms\"",
+ );
+ PRODUCT_NAME = qmltest;
+ };
+ name = Debug;
+ };
+ D3CAA7F513264F52008BB877 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
+ COPY_PHASE_STRIP = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = qmltest_Prefix.pch;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/include\"/**";
+ INFOPLIST_FILE = "qmltest-Info.plist";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/lib\"",
+ "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/plugins/platforms\"",
+ );
+ PRODUCT_NAME = qmltest;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "qmltest simulator" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D6058940D05DD3E006BFB54 /* Debug */,
+ 1D6058950D05DD3E006BFB54 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "qmltest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D3CAA7F313264F52008BB877 /* Build configuration list for PBXNativeTarget "qmltest device" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D3CAA7F413264F52008BB877 /* Debug */,
+ D3CAA7F513264F52008BB877 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch b/src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch
new file mode 100644
index 0000000000..c06715c661
--- /dev/null
+++ b/src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch
@@ -0,0 +1,8 @@
+//
+// Prefix header for all source files of the 'qmltest' target in the 'qmltest' project
+//
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+ #import <UIKit/UIKit.h>
+#endif
diff --git a/src/plugins/platforms/uikit/main.mm b/src/plugins/platforms/uikit/main.mm
new file mode 100644
index 0000000000..1ef69fa897
--- /dev/null
+++ b/src/plugins/platforms/uikit/main.mm
@@ -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$
+** 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 <UIKit/UIKit.h>
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "quikitintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QUIKitIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "UIKit";
+ return list;
+}
+
+QPlatformIntegration * QUIKitIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "uikit")
+ return new QUIKitIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(UIKit, QUIKitIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikiteventloop.h b/src/plugins/platforms/uikit/quikiteventloop.h
new file mode 100644
index 0000000000..b81e0fd75c
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikiteventloop.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$
+** 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 QUIKITEVENTLOOP_H
+#define QUIKITEVENTLOOP_H
+
+#include "quikitsoftwareinputhandler.h"
+
+#include <QtCore/QEvent>
+#include <QtGui/QPlatformEventLoopIntegration>
+
+@class EventLoopHelper;
+@class NSTimer;
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitEventLoop : public QPlatformEventLoopIntegration
+{
+public:
+ QUIKitEventLoop();
+ ~QUIKitEventLoop();
+
+ void startEventLoop();
+ void quitEventLoop();
+ void qtNeedsToProcessEvents();
+
+ EventLoopHelper *mHelper;
+ NSTimer *mTimer;
+ QUIKitSoftwareInputHandler *mInputHandler;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm
new file mode 100644
index 0000000000..8d2603c60d
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikiteventloop.mm
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** 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 "quikiteventloop.h"
+#include "quikitwindow.h"
+#include "quikitwindowsurface.h"
+
+#include <UIKit/UIKit.h>
+
+#include <QtGui/QApplication>
+#include <QtGui/QWidget>
+#include <QtDebug>
+
+@interface QUIKitAppDelegate : NSObject <UIApplicationDelegate> {
+}
+@end
+
+@interface EventLoopHelper : NSObject {
+ QUIKitEventLoop *mIntegration;
+}
+
+- (id)initWithEventLoopIntegration:(QUIKitEventLoop *)integration;
+
+- (void)processEvents;
+- (void)processEventsAndSchedule;
+
+@end
+
+@implementation QUIKitAppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ Q_UNUSED(launchOptions)
+ foreach (QWidget *widget, qApp->topLevelWidgets()) {
+ QRect geom = widget->geometry();
+ CGRect bar = application.statusBarFrame;
+ if (geom.y() <= bar.size.height) {
+ geom.setY(bar.size.height);
+ widget->setGeometry(geom);
+ }
+ QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
+ platformWindow->ensureNativeWindow();
+ }
+ return YES;
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+ Q_UNUSED(application)
+ // TODO this isn't called for some reason
+ qDebug() << "quit";
+ qApp->quit();
+}
+
+@end
+
+@implementation EventLoopHelper
+
+- (id)initWithEventLoopIntegration:(QUIKitEventLoop *)integration
+{
+ if ((self = [self init])) {
+ mIntegration = integration;
+ }
+ return self;
+}
+
+- (void)processEvents
+{
+ QPlatformEventLoopIntegration::processEvents();
+}
+
+- (void)processEventsAndSchedule
+{
+ QPlatformEventLoopIntegration::processEvents();
+ qint64 nextTime = mIntegration->nextTimerEvent();
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ NSDate *nextDate = [[NSDate date] dateByAddingTimeInterval:((double)nextTime/1000)];
+ [mIntegration->mTimer setFireDate:nextDate];
+ [pool release];
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+
+QUIKitEventLoop::QUIKitEventLoop()
+{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ mInputHandler = new QUIKitSoftwareInputHandler;
+ mHelper = [[EventLoopHelper alloc] initWithEventLoopIntegration:this];
+ mTimer = [[NSTimer timerWithTimeInterval:0.030 target:mHelper selector:@selector(processEventsAndSchedule) userInfo:nil repeats:YES] retain];
+ [pool release];
+}
+
+QUIKitEventLoop::~QUIKitEventLoop()
+{
+ [mTimer release];
+ [mHelper release];
+ delete mInputHandler;
+}
+
+void QUIKitEventLoop::startEventLoop()
+{
+ qApp->installEventFilter(mInputHandler);
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ [[NSRunLoop currentRunLoop] addTimer:[mTimer autorelease] forMode:NSDefaultRunLoopMode];
+ UIApplicationMain(qApp->argc(), qApp->argv(), nil, @"QUIKitAppDelegate");
+ [pool release];
+}
+
+void QUIKitEventLoop::quitEventLoop()
+{
+
+}
+
+void QUIKitEventLoop::qtNeedsToProcessEvents()
+{
+ [mHelper performSelectorOnMainThread:@selector(processEvents) withObject:nil waitUntilDone:NO];
+}
+
+bool QUIKitSoftwareInputHandler::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::RequestSoftwareInputPanel) {
+ QWidget *widget = qobject_cast<QWidget *>(obj);
+ if (widget) {
+ QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
+ [platformWindow->nativeView() becomeFirstResponder];
+ return true;
+ }
+ } else if (event->type() == QEvent::CloseSoftwareInputPanel) {
+ QWidget *widget = qobject_cast<QWidget *>(obj);
+ if (widget) {
+ QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
+ [platformWindow->nativeView() resignFirstResponder];
+ return true;
+ }
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitintegration.h b/src/plugins/platforms/uikit/quikitintegration.h
new file mode 100644
index 0000000000..a986e92b3f
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitintegration.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$
+** 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 QPLATFORMINTEGRATION_UIKIT_H
+#define QPLATFORMINTEGRATION_UIKIT_H
+
+#include <QtGui/QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitIntegration : public QPlatformIntegration
+{
+public:
+ QUIKitIntegration();
+ ~QUIKitIntegration();
+
+ 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;
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+ QPlatformEventLoopIntegration *createEventLoopIntegration() const;
+
+private:
+ QList<QPlatformScreen *> mScreens;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm
new file mode 100644
index 0000000000..d4b4192b60
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitintegration.mm
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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 "quikitintegration.h"
+#include "quikitwindow.h"
+#include "quikitwindowsurface.h"
+#include "quikitscreen.h"
+#include "quikiteventloop.h"
+
+#include <QtGui/QApplication>
+
+#include <private/qpixmap_raster_p.h>
+
+#include <UIKit/UIKit.h>
+
+#include <QtDebug>
+
+QT_BEGIN_NAMESPACE
+
+QUIKitIntegration::QUIKitIntegration()
+{
+ mScreens << new QUIKitScreen(0);
+}
+
+QUIKitIntegration::~QUIKitIntegration()
+{
+}
+
+QPixmapData *QUIKitIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QUIKitWindow(widget);
+}
+
+QList<QPlatformScreen *> QUIKitIntegration::screens() const
+{
+ return mScreens;
+}
+
+QWindowSurface *QUIKitIntegration::createWindowSurface(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QUIKitWindowSurface(widget);
+}
+
+QPlatformEventLoopIntegration *QUIKitIntegration::createEventLoopIntegration() const
+{
+ return new QUIKitEventLoop();
+}
+
+QPlatformFontDatabase * QUIKitIntegration::fontDatabase() const
+{
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+ setenv("QT_QPA_FONTDIR",[[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"fonts"] UTF8String],1);
+ }
+ return QPlatformIntegration::fontDatabase();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitscreen.h b/src/plugins/platforms/uikit/quikitscreen.h
new file mode 100644
index 0000000000..15c7d694d8
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitscreen.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$
+** 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 QUIKITSCREEN_H
+#define QUIKITSCREEN_H
+
+#include <UIKit/UIKit.h>
+
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitScreen : public QPlatformScreen
+{
+public:
+ QUIKitScreen(int screenIndex);
+ ~QUIKitScreen();
+
+ QRect geometry() const { return m_geometry; }
+ int depth() const { return m_depth; }
+ QImage::Format format() const { return m_format; }
+ QSize physicalSize() const { return m_physicalSize; }
+
+ UIScreen *uiScreen() const;
+
+private:
+ QRect m_geometry;
+ int m_depth;
+ QImage::Format m_format;
+ QSize m_physicalSize;
+ int m_index;
+};
+
+QT_END_NAMESPACE
+
+
+#endif
diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm
new file mode 100644
index 0000000000..21494c9385
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitscreen.mm
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 "quikitscreen.h"
+
+#include <QtGui/QApplication>
+
+#include <QtDebug>
+
+QT_BEGIN_NAMESPACE
+
+QUIKitScreen::QUIKitScreen(int screenIndex)
+ : QPlatformScreen(),
+ m_index(screenIndex)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex];
+ CGRect bounds = [screen bounds];
+ m_geometry = QRect(0, 0, bounds.size.width, bounds.size.height);
+
+ m_format = QImage::Format_ARGB32;
+
+ m_depth = 24;
+
+ const qreal inch = 25.4;
+ qreal dpi = 160.;
+ int dragDistance = 14;
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
+ dpi = 132.;
+ dragDistance = 10;
+ }
+ m_physicalSize = QSize(qRound(bounds.size.width * inch / dpi), qRound(bounds.size.height * inch / dpi));
+ qApp->setStartDragDistance(dragDistance);
+ [pool release];
+}
+
+QUIKitScreen::~QUIKitScreen()
+{
+}
+
+UIScreen *QUIKitScreen::uiScreen() const
+{
+ return [[UIScreen screens] objectAtIndex:m_index];
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitsoftwareinputhandler.h b/src/plugins/platforms/uikit/quikitsoftwareinputhandler.h
new file mode 100644
index 0000000000..629fd13815
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitsoftwareinputhandler.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$
+** 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 QUIKITSOFTWAREINPUTHANDLER_H
+#define QUIKITSOFTWAREINPUTHANDLER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitSoftwareInputHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ bool eventFilter(QObject *obj, QEvent *event);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h
new file mode 100644
index 0000000000..9e73754fc8
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitwindow.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** 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 QUIKITWINDOW_H
+#define QUIKITWINDOW_H
+
+#include <QPlatformWindow>
+
+#import <UIKit/UIKit.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+#import <OpenGLES/EAGL.h>
+
+@interface EAGLView : UIView <UIKeyInput>
+{
+ QPlatformWindow *mWindow;
+ EAGLContext *mContext;
+
+ GLint mFramebufferWidth;
+ GLint mFramebufferHeight;
+
+ GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer;
+
+ // ------- Text Input ----------
+ UITextAutocapitalizationType autocapitalizationType;
+ UITextAutocorrectionType autocorrectionType;
+ BOOL enablesReturnKeyAutomatically;
+ UIKeyboardAppearance keyboardAppearance;
+ UIKeyboardType keyboardType;
+ UIReturnKeyType returnKeyType;
+ BOOL secureTextEntry;
+}
+
+- (void)setContext:(EAGLContext *)newContext;
+- (void)presentFramebuffer;
+- (void)deleteFramebuffer;
+- (void)createFramebuffer;
+- (void)makeCurrent;
+- (void)setWindow:(QPlatformWindow *)window;
+- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons;
+
+
+// ------- Text Input ----------
+
+@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
+@property(nonatomic) UITextAutocorrectionType autocorrectionType;
+@property(nonatomic) BOOL enablesReturnKeyAutomatically;
+@property(nonatomic) UIKeyboardAppearance keyboardAppearance;
+@property(nonatomic) UIKeyboardType keyboardType;
+@property(nonatomic) UIReturnKeyType returnKeyType;
+@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry;
+
+@end
+
+class EAGLPlatformContext;
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitScreen;
+
+class QUIKitWindow : public QPlatformWindow
+{
+public:
+ explicit QUIKitWindow(QWidget *tlw);
+ ~QUIKitWindow();
+
+ UIWindow *nativeWindow() const { return mWindow; }
+ UIView *nativeView() const { return mView; }
+ void setGeometry(const QRect &rect);
+
+ UIWindow *ensureNativeWindow();
+
+ QPlatformGLContext *glContext() const;
+
+private:
+ QUIKitScreen *mScreen;
+ UIWindow *mWindow;
+ EAGLView *mView;
+ mutable EAGLPlatformContext *mContext;
+};
+
+QT_END_NAMESPACE
+
+#endif // QUIKITWINDOW_H
diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm
new file mode 100644
index 0000000000..52d184636e
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitwindow.mm
@@ -0,0 +1,375 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#import <QuartzCore/CAEAGLLayer.h>
+
+#include "quikitwindow.h"
+
+#include "quikitscreen.h"
+
+#include <QtDebug>
+#include <QtGui/QApplication>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtDebug>
+
+class EAGLPlatformContext : public QPlatformGLContext
+{
+public:
+ EAGLPlatformContext(EAGLView *view)
+ : mView(view)
+ {
+ mFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
+ mFormat.setDepthBufferSize(24);
+ mFormat.setAccumBufferSize(0);
+ mFormat.setRedBufferSize(8);
+ mFormat.setGreenBufferSize(8);
+ mFormat.setBlueBufferSize(8);
+ mFormat.setAlphaBufferSize(8);
+ mFormat.setStencilBufferSize(8);
+ mFormat.setSampleBuffers(false);
+ mFormat.setSamples(1);
+// mFormat.setSwapInterval(?)
+ mFormat.setDoubleBuffer(true);
+ mFormat.setDepth(true);
+ mFormat.setRgba(true);
+ mFormat.setAlpha(true);
+ mFormat.setAccum(false);
+ mFormat.setStencil(true);
+ mFormat.setStereo(false);
+ mFormat.setDirectRendering(false);
+
+ EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+ [mView setContext:aContext];
+ }
+
+ ~EAGLPlatformContext() { }
+
+ void makeCurrent()
+ {
+ QPlatformGLContext::makeCurrent();
+ [mView makeCurrent];
+ }
+
+ void doneCurrent()
+ {
+ QPlatformGLContext::doneCurrent();
+ }
+
+ void swapBuffers()
+ {
+ [mView presentFramebuffer];
+ }
+
+ void* getProcAddress(const QString& ) { return 0; }
+
+ QPlatformWindowFormat platformWindowFormat() const
+ {
+ return mFormat;
+ }
+
+private:
+ EAGLView *mView;
+
+ QPlatformWindowFormat mFormat;
+};
+
+@implementation EAGLView
+
++ (Class)layerClass
+{
+ return [CAEAGLLayer class];
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame])) {
+ CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+ eaglLayer.opaque = TRUE;
+ eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
+ kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+ nil];
+ autocapitalizationType = UITextAutocapitalizationTypeNone;
+ autocorrectionType = UITextAutocorrectionTypeNo;
+ enablesReturnKeyAutomatically = NO;
+ keyboardAppearance = UIKeyboardAppearanceDefault;
+ keyboardType = UIKeyboardTypeDefault;
+ returnKeyType = UIReturnKeyDone;
+ secureTextEntry = NO;
+ }
+ return self;
+}
+
+- (void)setContext:(EAGLContext *)newContext
+{
+ if (mContext != newContext)
+ {
+ [self deleteFramebuffer];
+ [mContext release];
+ mContext = [newContext retain];
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)presentFramebuffer
+{
+ if (mContext) {
+ [EAGLContext setCurrentContext:mContext];
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer);
+ [mContext presentRenderbuffer:GL_RENDERBUFFER_OES];
+ }
+}
+
+- (void)deleteFramebuffer
+{
+ if (mContext)
+ {
+ [EAGLContext setCurrentContext:mContext];
+ if (mFramebuffer) {
+ glDeleteFramebuffersOES(1, &mFramebuffer);
+ mFramebuffer = 0;
+ }
+ if (mColorRenderbuffer) {
+ glDeleteRenderbuffersOES(1, &mColorRenderbuffer);
+ mColorRenderbuffer = 0;
+ }
+ if (mDepthRenderbuffer) {
+ glDeleteRenderbuffersOES(1, &mDepthRenderbuffer);
+ mDepthRenderbuffer = 0;
+ }
+ }
+}
+
+- (void)createFramebuffer
+{
+ if (mContext && !mFramebuffer)
+ {
+ [EAGLContext setCurrentContext:mContext];
+ glGenFramebuffersOES(1, &mFramebuffer);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer);
+
+ glGenRenderbuffersOES(1, &mColorRenderbuffer);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer);
+ [mContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer];
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mFramebufferWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mFramebufferHeight);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mColorRenderbuffer);
+
+ glGenRenderbuffersOES(1, &mDepthRenderbuffer);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer);
+ glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
+
+ if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
+ NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+ }
+}
+
+- (void)makeCurrent
+{
+ if (mContext)
+ {
+ [EAGLContext setCurrentContext:mContext];
+ if (!mFramebuffer)
+ [self createFramebuffer];
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer);
+ glViewport(0, 0, mFramebufferWidth, mFramebufferHeight);
+ }
+}
+
+- (void)setWindow:(QPlatformWindow *)window
+{
+ mWindow = window;
+}
+
+- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons
+{
+ UITouch *touch = [touches anyObject];
+ CGPoint locationInView = [touch locationInView:self];
+ QPoint p(locationInView.x, locationInView.y);
+ // TODO handle global touch point? for status bar?
+ QWindowSystemInterface::handleMouseEvent(mWindow->widget(), (ulong)(event.timestamp*1000),
+ p, p, buttons);
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
+}
+
+// ------- Text Input ----------
+
+@synthesize autocapitalizationType;
+@synthesize autocorrectionType;
+@synthesize enablesReturnKeyAutomatically;
+@synthesize keyboardAppearance;
+@synthesize keyboardType;
+@synthesize returnKeyType;
+@synthesize secureTextEntry;
+
+- (BOOL)canBecomeFirstResponder
+{
+ return YES;
+}
+
+- (BOOL)hasText
+{
+ return YES;
+}
+
+- (void)insertText:(NSString *)text
+{
+ QKeyEvent *ev;
+ int key = 0;
+ if ([text isEqualToString:@"\n"])
+ key = (int)Qt::Key_Return;
+ ev = new QKeyEvent(QEvent::KeyPress,
+ key,
+ Qt::NoModifier,
+ QString::fromUtf8([text UTF8String])
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+ ev = new QKeyEvent(QEvent::KeyRelease,
+ key,
+ Qt::NoModifier,
+ QString::fromUtf8([text UTF8String])
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+}
+
+- (void)deleteBackward
+{
+ QKeyEvent *ev;
+ ev = new QKeyEvent(QEvent::KeyPress,
+ (int)Qt::Key_Backspace,
+ Qt::NoModifier
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+ ev = new QKeyEvent(QEvent::KeyRelease,
+ (int)Qt::Key_Backspace,
+ Qt::NoModifier
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+
+QUIKitWindow::QUIKitWindow(QWidget *tlw) :
+ QPlatformWindow(tlw),
+ mWindow(nil),
+ mContext(0)
+{
+ mScreen = static_cast<QUIKitScreen *>(QPlatformScreen::platformScreenForWidget(tlw));
+ CGRect screenBounds = [mScreen->uiScreen() bounds];
+ QRect geom(screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height);
+ setGeometry(geom);
+ // TODO ensure the native window if the application is already running
+}
+
+QUIKitWindow::~QUIKitWindow()
+{
+ delete mContext; mContext = 0;
+ [mView release];
+ [mWindow release];
+}
+
+void QUIKitWindow::setGeometry(const QRect &rect)
+{
+ if (mWindow) {
+ mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
+ mView.frame = CGRectMake(0, 0, rect.width(), rect.height());
+ [mView deleteFramebuffer];
+ [mWindow setNeedsDisplay];
+ }
+ QPlatformWindow::setGeometry(rect);
+}
+
+UIWindow *QUIKitWindow::ensureNativeWindow()
+{
+ if (!mWindow) {
+ // window
+ QRect geom = geometry();
+ CGRect frame = CGRectMake(geom.x(), geom.y(), geom.width(), geom.height());
+ mWindow = [[UIWindow alloc] initWithFrame:frame];
+ mWindow.screen = mScreen->uiScreen();
+ mWindow.frame = frame; // for some reason setting the screen resets frame.origin
+
+ // view
+ mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, geom.width(), geom.height())];
+ [mView setMultipleTouchEnabled:YES];
+ [mView setWindow:this];
+ [mWindow addSubview:mView];
+ [mWindow setNeedsDisplay];
+ [mWindow makeKeyAndVisible];
+ }
+ return mWindow;
+}
+
+QPlatformGLContext *QUIKitWindow::glContext() const
+{
+ if (!mContext) {
+ mContext = new EAGLPlatformContext(mView);
+ }
+ return mContext;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.h b/src/plugins/platforms/uikit/quikitwindowsurface.h
new file mode 100644
index 0000000000..ca10a710eb
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitwindowsurface.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** 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 QUIKITWINDOWSURFACE_H
+#define QUIKITWINDOWSURFACE_H
+
+#include <QtGui/QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitWindowSurface : public QWindowSurface
+{
+public:
+ QUIKitWindowSurface(QWidget *window);
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ WindowSurfaceFeatures features() const;
+
+private:
+ QPaintDevice *mPaintDevice;
+};
+
+QT_END_NAMESPACE
+
+#endif // QUIKITWINDOWSURFACE_H
diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.mm b/src/plugins/platforms/uikit/quikitwindowsurface.mm
new file mode 100644
index 0000000000..bb7dcd794b
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitwindowsurface.mm
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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 "quikitwindowsurface.h"
+#include "quikitwindow.h"
+
+#include <QtOpenGL/private/qgl_p.h>
+#include <QtOpenGL/private/qglpaintdevice_p.h>
+
+#include <QtDebug>
+
+class EAGLPaintDevice : public QGLPaintDevice
+{
+public:
+ EAGLPaintDevice(QPlatformWindow *window)
+ :QGLPaintDevice(), mWindow(window)
+ {
+ }
+
+ int devType() const { return QInternal::OpenGL; }
+ QSize size() const { return mWindow->geometry().size(); }
+ QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); }
+
+ QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
+
+ void beginPaint(){
+ QGLPaintDevice::beginPaint();
+ }
+private:
+ QPlatformWindow *mWindow;
+};
+
+QT_BEGIN_NAMESPACE
+
+QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window)
+ : QWindowSurface(window), mPaintDevice(new EAGLPaintDevice(window->platformWindow()))
+{
+}
+
+QPaintDevice *QUIKitWindowSurface::paintDevice()
+{
+ return mPaintDevice;
+}
+
+void QUIKitWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+ widget->platformWindow()->glContext()->swapBuffers();
+}
+
+QWindowSurface::WindowSurfaceFeatures QUIKitWindowSurface::features() const
+{
+ return PartialUpdates;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/uikit.pro b/src/plugins/platforms/uikit/uikit.pro
new file mode 100644
index 0000000000..6f5947f2c0
--- /dev/null
+++ b/src/plugins/platforms/uikit/uikit.pro
@@ -0,0 +1,27 @@
+TARGET = quikit
+include(../../qpluginbase.pri)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+QT += opengl
+
+OBJECTIVE_SOURCES = main.mm \
+ quikitintegration.mm \
+ quikitwindow.mm \
+ quikitscreen.mm \
+ quikiteventloop.mm \
+ quikitwindowsurface.mm
+
+OBJECTIVE_HEADERS = quikitintegration.h \
+ quikitwindow.h \
+ quikitscreen.h \
+ quikiteventloop.h \
+ quikitwindowsurface.h
+
+HEADERS = quikitsoftwareinputhandler.h
+
+#add libz for freetype.
+LIBS += -lz
+
+#include(../fontdatabases/basicunix/basicunix.pri)
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/vnc/main.cpp b/src/plugins/platforms/vnc/main.cpp
new file mode 100644
index 0000000000..890b8f86ad
--- /dev/null
+++ b/src/plugins/platforms/vnc/main.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 "qvncintegration.h"
+#include <qstringlist.h>
+#include <QtGui/QPlatformIntegrationPlugin>
+
+QT_BEGIN_NAMESPACE
+
+class QVNCIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList &);
+};
+
+QStringList QVNCIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "VNC";
+ return list;
+}
+
+QPlatformIntegration* QVNCIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "vnc")
+ return new QVNCIntegration(paramList);
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(vnc, QVNCIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvnccursor.cpp b/src/plugins/platforms/vnc/qvnccursor.cpp
new file mode 100644
index 0000000000..dbcdef3ddd
--- /dev/null
+++ b/src/plugins/platforms/vnc/qvnccursor.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** 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 <QPainter>
+#include <QTcpSocket>
+#include <arpa/inet.h>
+#include <QBitmap>
+#include <QApplication>
+
+#include <QDebug>
+
+#include "qvnccursor.h"
+#include "qvncserver.h"
+#include "qvncintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+QVNCCursor::QVNCCursor(QVNCServer * srvr, QVNCScreen *scr )
+ :QPlatformSoftwareCursor(scr), useVncCursor(false), server(srvr)
+{
+}
+
+void QVNCCursor::changeCursor(QCursor * widgetCursor, QWidget * widget)
+{
+ QPlatformSoftwareCursor::changeCursor(widgetCursor, widget);
+ if (useVncCursor) {
+ server->setDirtyCursor();
+ } else {
+ setDirty();
+ }
+}
+
+void QVNCCursor::setCursorMode(bool vnc)
+{
+ if (vnc) {
+ setDirty();
+ server->setDirtyCursor();
+ } else {
+ server->setDirtyCursor();
+ }
+ useVncCursor = vnc;
+}
+
+QRect QVNCCursor::drawCursor(QPainter & painter)
+{
+ if (useVncCursor)
+ return QRect();
+
+ return QPlatformSoftwareCursor::drawCursor(painter);
+}
+
+void QVNCCursor::clearClientCursor()
+{
+ QTcpSocket *socket = server->clientSocket();
+ if (!socket) {
+ return;
+ }
+ // FramebufferUpdate header
+ {
+ const quint16 tmp[6] = { htons(0),
+ htons(1),
+ htons(0), htons(0),
+ htons(0),
+ htons(0) };
+ socket->write((char*)tmp, sizeof(tmp));
+
+ const quint32 encoding = htonl(-239);
+ socket->write((char*)(&encoding), sizeof(encoding));
+ }
+}
+
+void QVNCCursor::sendClientCursor()
+{
+ if (useVncCursor == false) {
+ clearClientCursor();
+ return;
+ }
+ QImage *image = graphic->image();
+ if (image->isNull())
+ return;
+ QTcpSocket *socket = server->clientSocket();
+ if (!socket) {
+ return;
+ }
+ // FramebufferUpdate header
+ {
+ const quint16 tmp[6] = { htons(0),
+ htons(1),
+ htons(graphic->hotspot().x()), htons(graphic->hotspot().y()),
+ htons(image->width()),
+ htons(image->height()) };
+ socket->write((char*)tmp, sizeof(tmp));
+
+ const quint32 encoding = htonl(-239);
+ socket->write((char*)(&encoding), sizeof(encoding));
+ }
+
+ // write pixels
+ //Q_ASSERT(cursor->hasAlphaChannel());
+ const QImage img = image->convertToFormat(QImage::Format_RGB32);
+ 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 = image->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);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvnccursor.h b/src/plugins/platforms/vnc/qvnccursor.h
new file mode 100644
index 0000000000..8eb26e08bf
--- /dev/null
+++ b/src/plugins/platforms/vnc/qvnccursor.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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 QVNCCURSOR_H
+#define QVNCCURSOR_H
+
+#include "../fb_base/fb_base.h"
+#include <QList>
+#include <QImage>
+#include <QMouseEvent>
+
+QT_BEGIN_NAMESPACE
+
+class QVNCScreen;
+class QVNCServer;
+
+class QVNCCursor : public QPlatformSoftwareCursor {
+public:
+ QVNCCursor(QVNCServer *, QVNCScreen *);
+
+ // input methods
+ void setCursorMode(bool vnc);
+ void changeCursor(QCursor * widgetCursor, QWidget * widget);
+
+ // output methods
+ QRect drawCursor(QPainter &);
+
+ // VNC client communication
+ void sendClientCursor();
+ void clearClientCursor();
+private:
+ bool useVncCursor; // VNC or local
+
+ QVNCServer * server; // VNC server to get events from
+};
+
+QT_END_NAMESPACE
+
+#endif // QVNCCURSOR_H
diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
new file mode 100644
index 0000000000..b99ff3f2f2
--- /dev/null
+++ b/src/plugins/platforms/vnc/qvncintegration.cpp
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** 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 "qvncintegration.h"
+#include "../fb_base/fb_base.h"
+#include <private/qapplication_p.h>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtCore/qdebug.h>
+
+#include <qvncserver.h>
+#include <QtGui/QPainter>
+
+#include <QtCore/QTimer>
+#include "qgenericunixfontdatabase.h"
+
+QVNCScreen::QVNCScreen(QRect screenSize, int screenId)
+ : QFbScreen::QFbScreen()
+{
+ setGeometry(screenSize);
+ setDepth(32);
+ setFormat(QImage::Format_RGB32);
+ setPhysicalSize((geometry().size()*254)/720);
+
+
+ d_ptr = new QVNCScreenPrivate(this, screenId);
+
+ cursor = new QVNCCursor(d_ptr->vncServer, this);
+ d_ptr->vncServer->setCursor(static_cast<QVNCCursor *>(cursor));
+}
+
+QVNCDirtyMap *QVNCScreen::dirtyMap()
+{
+ return d_ptr->dirty;
+}
+
+QRegion QVNCScreen::doRedraw()
+{
+ QRegion touched;
+ touched = QFbScreen::doRedraw();
+
+ QVector<QRect> rects = touched.rects();
+ for (int i = 0; i < rects.size(); i++)
+ d_ptr->setDirty(rects[i]);
+ return touched;
+}
+
+static inline int defaultWidth() { return 800; }
+static inline int defaultHeight() { return 600; }
+static inline int defaultDisplay() { return 0; }
+
+static void usage()
+{
+ qWarning() << "VNC Platform Integration options:";
+ qWarning() << " size=<Width>x<Height> - set the display width and height";
+ qWarning() << " defaults to" << defaultWidth() << "x" << defaultHeight();
+ qWarning() << " display=<ID> - set the VNC display port to ID + 5900";
+ qWarning() << " defaults to" << defaultDisplay();
+ qWarning() << " offset=<X>x<Y> - set the current screens offset";
+ qWarning() << " vnc - start configuration of a new screen";
+ qWarning() << " size and offset are inherited from the previous screen if not set";
+ qWarning() << " display id is incremented from the previous screen if not set";
+ qWarning() << " virtual - manage the set of screens as a virtual desktop";
+}
+
+QVNCIntegration::QVNCIntegration(const QStringList& paramList)
+ : virtualDesktop(false), fontDb(new QGenericUnixFontDatabase())
+{
+ int sizeX = defaultWidth();
+ int sizeY = defaultHeight();
+ int offsetX = 0;
+ int offsetY = 0;
+ int display = defaultDisplay();
+ bool showUsage = false;
+
+ foreach(QString confString, paramList) {
+ if (confString.startsWith(QLatin1String("size="))) {
+ QString val = confString.section(QLatin1Char('='), 1, 1);
+ sizeX = val.section(QLatin1Char('x'), 0, 0).toInt();
+ sizeY = val.section(QLatin1Char('x'), 1, 1).toInt();
+ }
+ else if (confString.startsWith(QLatin1String("display="))) {
+ display = confString.section(QLatin1Char('='), 1, 1).toInt();
+ }
+ else if (confString.startsWith(QLatin1String("offset="))) {
+ QString val = confString.section(QLatin1Char('='), 1, 1);
+ offsetX = val.section(QLatin1Char('x'), 0, 0).toInt();
+ offsetY = val.section(QLatin1Char('x'), 1, 1).toInt();
+ }
+ else if (confString == QLatin1String("vnc")) {
+ QRect screenRect(offsetX, offsetY, sizeX, sizeY);
+ QVNCScreen *screen = new QVNCScreen(screenRect, display);
+ mScreens.append(screen);
+ screen->setObjectName(QString("screen %1").arg(display));
+ screen->setDirty(screenRect);
+ ++display;
+ }
+ else if (confString == QLatin1String("virtual")) {
+ virtualDesktop = true;
+ }
+ else {
+ qWarning() << "Unknown VNC option:" << confString;
+ showUsage = true;
+ }
+ }
+
+ if (showUsage)
+ usage();
+
+ QRect screenRect(offsetX, offsetY, sizeX, sizeY);
+ QVNCScreen *screen = new QVNCScreen(screenRect, display);
+ mScreens.append(screen);
+ mPrimaryScreen = qobject_cast<QVNCScreen *>(mScreens.first());
+ screen->setObjectName(QString("screen %1").arg(display));
+ screen->setDirty(screenRect);
+}
+
+bool QVNCIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+
+QPixmapData *QVNCIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
+{
+ QFbWindowSurface * surface;
+ surface = new QFbWindowSurface(mPrimaryScreen, widget);
+ return surface;
+}
+
+
+QPlatformWindow *QVNCIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
+{
+ QFbWindow *w = new QFbWindow(widget);
+ if (virtualDesktop) {
+ QList<QPlatformScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QPlatformScreen *>::const_iterator end = mScreens.constEnd();
+ QFbScreen *screen;
+ while (i != end) {
+ screen = static_cast<QFbScreen *>(*i);
+ screen->addWindow(w);
+ ++i;
+ }
+ }
+ else
+ mPrimaryScreen->addWindow(w);
+ return w;
+}
+
+QPixmap QVNCIntegration::grabWindow(WId window, int x, int y, int width, int height) const
+{
+// qDebug() << "QVNCIntegration::grabWindow" << window << x << y << width << height;
+
+ if (window == 0) { //desktop
+ QImage *desktopImage = mPrimaryScreen->image();
+ if (x==0 && y == 0 && width < 0 && height < 0) {
+ return QPixmap::fromImage(*desktopImage);
+ }
+ if (width < 0)
+ width = desktopImage->width() - x;
+ if (height < 0)
+ height = desktopImage->height() - y;
+ int bytesPerPixel = desktopImage->depth()/8; //We don't support 1, 2, or 4 bpp
+ QImage img(desktopImage->scanLine(y) + bytesPerPixel*x, width, height, desktopImage->bytesPerLine(), desktopImage->format());
+ return QPixmap::fromImage(img);
+ }
+ QWidget *win = QWidget::find(window);
+ if (win) {
+ QRect r = win->geometry();
+ if (width < 0)
+ width = r.width() - x;
+ if (height < 0)
+ height = r.height() - y;
+ QImage *desktopImage = mPrimaryScreen->image();
+ int bytesPerPixel = desktopImage->depth()/8; //We don't support 1, 2, or 4 bpp
+
+ QImage img(desktopImage->scanLine(r.top() + y) + bytesPerPixel*(r.left()+x), width, height, desktopImage->bytesPerLine(), desktopImage->format());
+ return QPixmap::fromImage(img);
+ }
+ return QPixmap();
+}
+
+
+void QVNCIntegration::moveToScreen(QWidget *window, int screen)
+{
+ if (virtualDesktop) { // all windows exist on all screens in virtual desktop mode
+ return;
+ }
+ if (screen < 0 || screen > mScreens.size())
+ return;
+ QVNCScreen * newScreen = qobject_cast<QVNCScreen *>(mScreens.at(screen));
+ for(int i = 0; i < mScreens.size(); i++) {
+ QVNCScreen *oldScreen = qobject_cast<QVNCScreen *>(mScreens.at(i));
+ if (oldScreen->windowStack.contains(static_cast<QFbWindow *>(window->platformWindow()))) {
+ oldScreen->removeWindow(static_cast<QFbWindow *>(window->platformWindow()));
+ break;
+ }
+ }
+ window->platformWindow()->setGeometry(window->geometry()); // this should be unified elsewhere
+ newScreen->addWindow(static_cast<QFbWindow *>(window->platformWindow()));
+}
+
+QPlatformFontDatabase *QVNCIntegration::fontDatabase() const
+{
+ return fontDb;
+}
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
new file mode 100644
index 0000000000..ef16dfade0
--- /dev/null
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** 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 QGRAPHICSSYSTEM_VNC_H
+#define QGRAPHICSSYSTEM_VNC_H
+
+#include "qvnccursor.h"
+#include "../fb_base/fb_base.h"
+#include <QPlatformIntegration>
+#include "qgenericunixfontdatabase.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVNCServer;
+class QVNCDirtyMap;
+
+class QVNCScreenPrivate;
+
+class QVNCScreen : public QFbScreen
+{
+ Q_OBJECT
+public:
+ QVNCScreen(QRect screenSize, int screenId);
+
+ int linestep() const { return image() ? image()->bytesPerLine() : 0; }
+ uchar *base() const { return image() ? image()->bits() : 0; }
+ QVNCDirtyMap *dirtyMap();
+
+public:
+ QVNCScreenPrivate *d_ptr;
+
+private:
+ QVNCServer *server;
+ QRegion doRedraw();
+ friend class QVNCIntegration;
+};
+
+class QVNCIntegrationPrivate;
+
+
+class QVNCIntegration : public QPlatformIntegration
+{
+public:
+ QVNCIntegration(const QStringList& paramList);
+
+ 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;
+
+ QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+
+ QList<QPlatformScreen *> screens() const { return mScreens; }
+
+ bool isVirtualDesktop() { return virtualDesktop; }
+ void moveToScreen(QWidget *window, int screen);
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+private:
+ QVNCScreen *mPrimaryScreen;
+ QList<QPlatformScreen *> mScreens;
+ bool virtualDesktop;
+ QPlatformFontDatabase *fontDb;
+};
+
+
+
+QT_END_NAMESPACE
+
+#endif //QGRAPHICSSYSTEM_VNC_H
+
diff --git a/src/plugins/platforms/vnc/qvncserver.cpp b/src/plugins/platforms/vnc/qvncserver.cpp
new file mode 100644
index 0000000000..be2de7c007
--- /dev/null
+++ b/src/plugins/platforms/vnc/qvncserver.cpp
@@ -0,0 +1,1935 @@
+/****************************************************************************
+**
+** 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 "qvncserver.h"
+
+#include <QtCore/qtimer.h>
+#include <QtCore/qregexp.h>
+#include <QtGui/qwidget.h>
+#include <QtGui/qpolygon.h>
+#include <QtGui/qpainter.h>
+
+#include <QtGui/qevent.h>
+#include <QWindowSystemInterface>
+
+#include <qplatformdefs.h>
+
+#include <qdebug.h>
+
+#include <stdlib.h>
+
+
+#define QT_QWS_VNC_DEBUG
+#define QT_NO_QWS_CURSOR //###
+
+
+QT_BEGIN_NAMESPACE
+
+
+
+//copied from qscreen_qws.h
+#ifndef QT_QWS_DEPTH16_RGB
+#define QT_QWS_DEPTH16_RGB 565
+#endif
+static const int qt_rbits = (QT_QWS_DEPTH16_RGB/100);
+static const int qt_gbits = (QT_QWS_DEPTH16_RGB/10%10);
+static const int qt_bbits = (QT_QWS_DEPTH16_RGB%10);
+static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits);
+static const int qt_green_shift = qt_bbits-(8-qt_gbits);
+static const int qt_neg_blue_shift = 8-qt_bbits;
+static const int qt_blue_mask = (1<<qt_bbits)-1;
+static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-(1<<qt_bbits);
+static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits));
+
+static const int qt_red_rounding_shift = qt_red_shift + qt_rbits;
+static const int qt_green_rounding_shift = qt_green_shift + qt_gbits;
+static const int qt_blue_rounding_shift = qt_bbits - qt_neg_blue_shift;
+
+
+inline QRgb qt_conv16ToRgb(ushort c)
+{
+ const int r=(c & qt_red_mask);
+ const int g=(c & qt_green_mask);
+ const int b=(c & qt_blue_mask);
+ const int tr = r >> qt_red_shift | r >> qt_red_rounding_shift;
+ const int tg = g >> qt_green_shift | g >> qt_green_rounding_shift;
+ const int tb = b << qt_neg_blue_shift | b >> qt_blue_rounding_shift;
+
+ return qRgb(tr,tg,tb);
+}
+
+
+
+//===========================================================================
+
+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 },
+ { 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) {
+ 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 = Qt::NoButton;
+ wheelDirection = WheelNone;
+ if (buttonMask & 1)
+ buttons |= Qt::LeftButton;
+ if (buttonMask & 2)
+ buttons |= Qt::MidButton;
+ if (buttonMask & 4)
+ buttons |= Qt::RightButton;
+ if (buttonMask & 8)
+ wheelDirection = WheelUp;
+ if (buttonMask & 16)
+ wheelDirection = WheelDown;
+ if (buttonMask & 32)
+ wheelDirection = WheelLeft;
+ if (buttonMask & 64)
+ wheelDirection = WheelRight;
+
+ 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), cursor(0)
+{
+ init(5900);
+}
+
+QVNCServer::QVNCServer(QVNCScreen *screen, int id)
+ : qvnc_screen(screen), cursor(0)
+{
+ init(5900 + id);
+}
+
+void QVNCServer::init(uint port)
+{
+ qDebug() << "QVNCServer::init" << 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())
+// 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->geometry().width();
+ sim.height = qvnc_screen->geometry().height();
+ 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 0//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
+ };
+
+ supportCursor = false;
+
+ 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
+ }
+
+ if (cursor)
+ cursor->setCursorMode(supportCursor);
+}
+
+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;
+ }
+}
+
+static bool buttonChange(Qt::MouseButtons before, Qt::MouseButtons after, Qt::MouseButton *button, bool *isPress)
+{
+ if (before == after)
+ return false;
+ for (int b = Qt::LeftButton; b <= Qt::MidButton; b<<=1) {
+ if ((before & b) != (after & b)) {
+ *button = static_cast<Qt::MouseButton>(b);
+ *isPress = (after & b);
+ return true;
+ }
+ }
+ return false;
+}
+
+void QVNCServer::pointerEvent()
+{
+ QPoint screenOffset = this->screen()->geometry().topLeft();
+
+ QRfbPointerEvent ev;
+ if (ev.read(client)) {
+ QPoint eventPoint(ev.x, ev.y);
+ eventPoint += screenOffset; // local to global translation
+
+ if (ev.wheelDirection == ev.WheelNone) {
+ QEvent::Type type = QEvent::MouseMove;
+ Qt::MouseButton button = Qt::NoButton;
+ bool isPress;
+ if (buttonChange(buttons, ev.buttons, &button, &isPress))
+ type = isPress ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
+ QWindowSystemInterface::handleMouseEvent(0, eventPoint, eventPoint, ev.buttons);
+ } else {
+ // No buttons or motion reported at the same time as wheel events
+ Qt::Orientation orientation;
+ if (ev.wheelDirection == ev.WheelLeft || ev.wheelDirection == ev.WheelRight)
+ orientation = Qt::Horizontal;
+ else
+ orientation = Qt::Vertical;
+ int delta = 120 * ((ev.wheelDirection == ev.WheelLeft || ev.wheelDirection == ev.WheelUp) ? 1 : -1);
+ QWindowSystemInterface::handleWheelEvent(0, eventPoint, eventPoint, delta, orientation);
+ }
+ 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) {
+// qDebug() << "keyEvent" << hex << ev.unicode << ev.keycode << keymod << ev.down;
+ QEvent::Type type = ev.down ? QEvent::KeyPress : QEvent::KeyRelease;
+ QString str;
+ if (ev.unicode && ev.unicode != 0xffff)
+ str = QString(ev.unicode);
+ QWindowSystemInterface::handleKeyEvent(0, type, ev.keycode, keymod, str);
+ }
+ 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 = false; //### 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
+#if 0
+ case 8: {
+ QRgb rgb = qvnc_screen->clut()[int(*src)];
+ r = qRed(rgb);
+ g = qGreen(rgb);
+ b = qBlue(rgb);
+ src++;
+ break;
+ }
+#endif
+#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(QVNCScreen *s)
+ : bytesPerPixel(0), numDirty(0), screen(s)
+{
+ bytesPerPixel = (screen->depth() + 7) / 8;
+ QSize screenSize = screen->geometry().size();
+ bufferWidth = screenSize.width();
+ bufferHeight = screenSize.height();
+ 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);
+
+ QSize screenSize = server->screen()->geometry().size();
+
+ for (int y = 0; y < map->mapHeight; ++y) {
+ if (rect.y + MAP_TILE_SIZE > screenSize.height())
+ rect.h = screenSize.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 > screenSize.width()) //###deviceWidth ???
+ rect.w = screenSize.width() - 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();
+ QSize screenSize = server->screen()->geometry().size();
+
+ // 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, screenSize.width(),
+ screenSize.height());
+ }
+ 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 qvnc_screen->image();
+}
+
+void QVNCServer::checkUpdate()
+{
+ if (!wantUpdate)
+ return;
+
+ if (dirtyCursor) {
+#ifndef QT_NO_QWS_CURSOR
+ Q_ASSERT(qvnc_cursor);
+ qvnc_cursor->write();
+#endif
+ cursor->sendClientCursor();
+ 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())
+// QWSServer::instance()->enablePainting(false);
+}
+
+
+
+QVNCScreenPrivate::QVNCScreenPrivate(QVNCScreen *parent, int screenId)
+ : dpiX(72), dpiY(72), doOnScreenSurface(false), refreshRate(25),
+ vncServer(0), q_ptr(parent)
+{
+#if 0//ndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->addObject(this);
+#endif
+
+ vncServer = new QVNCServer(q_ptr, screenId);
+ vncServer->setRefreshRate(refreshRate);
+
+
+ Q_ASSERT(q_ptr->depth() == 32);
+
+ dirty = new QVNCDirtyMapOptimized<quint32>(q_ptr);
+}
+
+QVNCScreenPrivate::~QVNCScreenPrivate()
+{
+}
+
+
+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()) {
+// qDebug() << "QVNCScreenPrivate::setDirty() - Not connected";
+ 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();
+}
+
+
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvncserver.h b/src/plugins/platforms/vnc/qvncserver.h
new file mode 100644
index 0000000000..3b514a5151
--- /dev/null
+++ b/src/plugins/platforms/vnc/qvncserver.h
@@ -0,0 +1,533 @@
+/****************************************************************************
+**
+** 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 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 "qvncintegration.h"
+#include "qvnccursor.h"
+#define QT_NO_QWS_CURSOR
+
+#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(QVNCScreen *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;
+ QVNCScreen *screen;
+ uchar *buffer;
+ int bufferWidth;
+ int bufferHeight;
+ int bufferStride;
+ int numTiles;
+};
+
+template <class T>
+class QVNCDirtyMapOptimized : public QVNCDirtyMap
+{
+public:
+ QVNCDirtyMapOptimized(QVNCScreen *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);
+
+ Qt::MouseButtons buttons;
+ enum { WheelNone,
+ WheelUp,
+ WheelDown,
+ WheelLeft,
+ WheelRight
+ } wheelDirection;
+ quint16 x;
+ quint16 y;
+};
+
+class QRfbClientCutText
+{
+public:
+ bool read(QTcpSocket *s);
+
+ quint32 length;
+};
+
+class QVNCScreenPrivate : public QObject
+{
+public:
+ QVNCScreenPrivate(QVNCScreen *parent, int screenId);
+ ~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;
+};
+
+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->dirtyMap(); }
+ 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
+
+ void setCursor(QVNCCursor * c) { cursor = c; }
+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;
+ Qt::MouseButtons buttons;
+ 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;
+ QVNCCursor *cursor;
+};
+
+
+QT_END_NAMESPACE
+#endif // QT_NO_QWS_VNC
+#endif // QSCREENVNC_P_H
diff --git a/src/plugins/platforms/vnc/vnc.pro b/src/plugins/platforms/vnc/vnc.pro
new file mode 100644
index 0000000000..07f8d888fd
--- /dev/null
+++ b/src/plugins/platforms/vnc/vnc.pro
@@ -0,0 +1,22 @@
+TARGET = qvncgraphicssystem
+include(../../qpluginbase.pri)
+
+QT += network
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+SOURCES = main.cpp qvncintegration.cpp
+HEADERS = qvncintegration.h
+
+HEADERS += qvncserver.h
+SOURCES += qvncserver.cpp
+
+HEADERS += qvnccursor.h
+SOURCES += qvnccursor.cpp
+
+include(../fb_base/fb_base.pri)
+include(../fontdatabases/genericunix/genericunix.pri)
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+
+INSTALLS += target
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
new file mode 100644
index 0000000000..d9b5fa9bff
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
@@ -0,0 +1,57 @@
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_WAYLAND_GL_SUPPORT
+ QT += opengl
+
+HEADERS += \
+ $$PWD/qwaylandglintegration.h \
+ $$PWD/qwaylandglwindowsurface.h
+
+SOURCES += \
+ $$PWD/qwaylandglintegration.cpp \
+ $$PWD/qwaylandglwindowsurface.cpp
+
+ QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
+ contains(QT_CONFIG, opengles2) {
+ isEqual(QT_WAYLAND_GL_CONFIG, wayland_egl) {
+ QT_WAYLAND_GL_INTEGRATION = $$QT_WAYLAND_GL_CONFIG
+ CONFIG += wayland_egl
+ } else:isEqual(QT_WAYLAND_GL_CONFIG,readback) {
+ QT_WAYLAND_GL_INTEGRATION = readback_egl
+ CONFIG += readback_egl
+ } else {
+ QT_WAYLAND_GL_INTEGRATION = xcomposite_egl
+ CONFIG += xcomposite_egl
+ }
+ } else {
+ isEqual(QT_WAYLAND_GL_CONFIG, readback) {
+ QT_WAYLAND_GL_INTEGRATION = readback_glx
+ CONFIG += readback_glx
+ } else {
+ QT_WAYLAND_GL_INTEGRATION = xcomposite_glx
+ CONFIG += xcomposite_glx
+ }
+ }
+
+ message("Wayland GL Integration: $$QT_WAYLAND_GL_INTEGRATION")
+}
+
+
+wayland_egl {
+ include ($$PWD/wayland_egl/wayland_egl.pri)
+}
+
+readback_egl {
+ include ($$PWD/readback_egl/readback_egl.pri)
+}
+
+readback_glx {
+ include ($$PWD/readback_glx/readback_glx.pri)
+}
+
+xcomposite_glx {
+ include ($$PWD/xcomposite_glx/xcomposite_glx.pri)
+}
+
+xcomposite_egl {
+ include ($$PWD/xcomposite_egl/xcomposite_egl.pri)
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp
new file mode 100644
index 0000000000..9c8ef4e986
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 "qwaylandglintegration.h"
+
+QWaylandGLIntegration::QWaylandGLIntegration()
+{
+
+}
+
+QWaylandGLIntegration::~QWaylandGLIntegration()
+{
+
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
new file mode 100644
index 0000000000..ac16039c9d
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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 QWAYLANDGLINTEGRATION_H
+#define QWAYLANDGLINTEGRATION_H
+
+class QWaylandWindow;
+class QWaylandDisplay;
+class QWidget;
+
+class QWaylandGLIntegration
+{
+public:
+ QWaylandGLIntegration();
+ virtual ~QWaylandGLIntegration();
+
+ virtual void initialize() = 0;
+
+ virtual QWaylandWindow *createEglWindow(QWidget *widget) = 0;
+
+ static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay);
+};
+
+#endif // QWAYLANDGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
new file mode 100644
index 0000000000..ebe4c7bf86
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** 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 "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);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
new file mode 100644
index 0000000000..8d53b42a56
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.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$
+** 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 QWAYLANDDRMSURFACE_H
+#define QWAYLANDDRMSURFACE_H
+
+#include "qwaylanddisplay.h"
+
+#include <QtGui/private/qwindowsurface_p.h>
+
+class QGLFramebufferObject;
+
+class QWaylandGLWindowSurface : public QWindowSurface
+{
+public:
+ QWaylandGLWindowSurface(QWidget *window);
+ ~QWaylandGLWindowSurface();
+
+ void beginPaint(const QRegion &);
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+
+ void resize(const QSize &size);
+
+private:
+ QWaylandDisplay *mDisplay;
+ QGLFramebufferObject *mPaintDevice;
+};
+
+#endif // QWAYLANDDRMSURFACE_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
new file mode 100644
index 0000000000..d63087d934
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** 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 "qwaylandreadbackeglcontext.h"
+
+#include "../../../eglconvenience/qeglconvenience.h"
+
+#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)
+{
+ const int width = img.width();
+ const int height = img.height();
+
+ if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
+ || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
+ {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
+ }
+ } else {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
+ }
+ }
+}
+
+QWaylandReadbackEglContext::QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window)
+ : mEglIntegration(eglIntegration)
+ , mWindow(window)
+ , mBuffer(0)
+ , mPixmap(0)
+ , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT))
+ , mPixmapSurface(EGL_NO_SURFACE)
+{
+ QVector<EGLint> eglContextAttrs;
+ eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ eglContextAttrs.append(2);
+ eglContextAttrs.append(EGL_NONE);
+
+ mContext = eglCreateContext(eglIntegration->eglDisplay(),mConfig,0,eglContextAttrs.constData());
+
+ geometryChanged();
+}
+
+QWaylandReadbackEglContext::~QWaylandReadbackEglContext()
+{
+ eglDestroyContext(mEglIntegration->eglDisplay(),mContext);
+}
+
+void QWaylandReadbackEglContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+
+ mWindow->waitForFrameSync();
+
+ eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext);
+}
+
+void QWaylandReadbackEglContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+}
+
+void QWaylandReadbackEglContext::swapBuffers()
+{
+ eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface);
+
+ if (QPlatformGLContext::currentContext() != this) {
+ makeCurrent();
+ }
+
+ QSize size = mWindow->geometry().size();
+
+ 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);
+
+ img = img.mirrored();
+ qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV);
+ constBits = img.bits();
+
+ const uchar *constDstBits = mBuffer->image()->bits();
+ uchar *dstBits = const_cast<uchar *>(constDstBits);
+ memcpy(dstBits,constBits,(img.width()*4) * img.height());
+
+
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+}
+
+void * QWaylandReadbackEglContext::getProcAddress(const QString &procName)
+{
+ return (void *) eglGetProcAddress(procName.toLatin1().data());
+}
+
+QPlatformWindowFormat QWaylandReadbackEglContext::platformWindowFormat() const
+{
+ return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+}
+
+void QWaylandReadbackEglContext::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;
+ if (mPixmap)
+ XFreePixmap(mEglIntegration->xDisplay(),mPixmap);
+
+ mBuffer = new QWaylandShmBuffer(mEglIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
+ mWindow->attach(mBuffer);
+ mPixmap = XCreatePixmap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),size.width(),size.height(),mEglIntegration->depth());
+ XSync(mEglIntegration->xDisplay(),False);
+
+ mPixmapSurface = eglCreatePixmapSurface(mEglIntegration->eglDisplay(),mConfig,mPixmap,0);
+ if (mPixmapSurface == EGL_NO_SURFACE) {
+ qDebug() << "Could not make egl surface out of pixmap :(";
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
new file mode 100644
index 0000000000..ac682759e9
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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 QWAYLANDREADBACKEGLGLCONTEXT_H
+#define QWAYLANDREADBACKEGLGLCONTEXT_H
+
+#include <QPlatformGLContext>
+#include <QtGui/QWidget>
+
+#include "qwaylandreadbackeglintegration.h"
+#include "qwaylandreadbackeglwindow.h"
+
+class QWaylandShmBuffer;
+
+class QWaylandReadbackEglContext : public QPlatformGLContext
+{
+public:
+ QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window);
+ ~QWaylandReadbackEglContext();
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ virtual QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandReadbackEglIntegration *mEglIntegration;
+ QWaylandReadbackEglWindow *mWindow;
+ QWaylandShmBuffer *mBuffer;
+
+ Pixmap mPixmap;
+
+ EGLConfig mConfig;
+ EGLContext mContext;
+ EGLSurface mPixmapSurface;
+};
+
+#endif // QWAYLANDREADBACKEGLGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
new file mode 100644
index 0000000000..20f7ffb609
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 "qwaylandreadbackeglintegration.h"
+
+#include <QDebug>
+
+#include "qwaylandreadbackeglwindow.h"
+
+QWaylandReadbackEglIntegration::QWaylandReadbackEglIntegration(QWaylandDisplay *display)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(display)
+{
+ qDebug() << "Using Readback-EGL";
+ char *display_name = getenv("DISPLAY");
+ mDisplay = XOpenDisplay(display_name);
+ mScreen = XDefaultScreen(mDisplay);
+ mRootWindow = XDefaultRootWindow(mDisplay);
+ XSync(mDisplay, False);
+}
+
+QWaylandReadbackEglIntegration::~QWaylandReadbackEglIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+
+QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandReadbackEglIntegration(waylandDisplay);
+}
+
+void QWaylandReadbackEglIntegration::initialize()
+{
+ eglBindAPI(EGL_OPENGL_ES_API);
+ mEglDisplay = eglGetDisplay(mDisplay);
+ EGLint major, minor;
+ EGLBoolean initialized = eglInitialize(mEglDisplay,&major,&minor);
+ if (initialized) {
+ qDebug() << "EGL initialized successfully" << major << "," << minor;
+ } else {
+ qDebug() << "EGL could not initialized. All EGL and GL operations will fail";
+ }
+}
+
+QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandReadbackEglWindow(widget,this);
+}
+
+EGLDisplay QWaylandReadbackEglIntegration::eglDisplay()
+{
+ return mEglDisplay;
+}
+
+Window QWaylandReadbackEglIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+int QWaylandReadbackEglIntegration::depth() const
+{
+ return XDefaultDepth(mDisplay,mScreen);
+}
+
+Display * QWaylandReadbackEglIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+QWaylandDisplay * QWaylandReadbackEglIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
new file mode 100644
index 0000000000..84fa64fd34
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.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$
+** 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 QWAYLANDREADBACKEGLINTEGRATION_H
+#define QWAYLANDREADBACKEGLINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <X11/Xlib.h>
+
+#include <EGL/egl.h>
+
+class QWaylandReadbackEglIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandReadbackEglIntegration(QWaylandDisplay *display);
+ ~QWaylandReadbackEglIntegration();
+
+ void initialize();
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+ Display *xDisplay() const;
+ Window rootWindow() const;
+ int depth() const;
+
+ EGLDisplay eglDisplay();
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ Display *mDisplay;
+ int mScreen;
+ Window mRootWindow;
+ EGLDisplay mEglDisplay;
+
+};
+
+#endif // QWAYLANDREADBACKEGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
new file mode 100644
index 0000000000..2ae212ba67
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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 "qwaylandreadbackeglwindow.h"
+
+#include "qwaylandreadbackeglcontext.h"
+
+QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration)
+ : QWaylandShmWindow(window)
+ , mEglIntegration(eglIntegration)
+ , mContext(0)
+{
+}
+
+QWaylandWindow::WindowType QWaylandReadbackEglWindow::windowType() const
+{
+ //We'r lying, maybe we should add a type, but for now it will do
+ //since this is primarly used by the windowsurface.
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext *QWaylandReadbackEglWindow::glContext() const
+{
+ if (!mContext) {
+ QWaylandReadbackEglWindow *that = const_cast<QWaylandReadbackEglWindow *>(this);
+ that->mContext = new QWaylandReadbackEglContext(mEglIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandReadbackEglWindow::setGeometry(const QRect &rect)
+{
+ QPlatformWindow::setGeometry(rect);
+
+ if (mContext)
+ mContext->geometryChanged();
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
new file mode 100644
index 0000000000..453ad27cd9
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** 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 QWAYLANDREADBACKEGLWINDOW_H
+#define QWAYLANDREADBACKEGLWINDOW_H
+
+#include "qwaylandshmwindow.h"
+#include "qwaylandreadbackeglintegration.h"
+
+class QWaylandReadbackEglContext;
+
+class QWaylandReadbackEglWindow : public QWaylandShmWindow
+{
+public:
+ QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration);
+
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandReadbackEglIntegration *mEglIntegration;
+ QWaylandReadbackEglContext *mContext;
+};
+
+#endif // QWAYLANDREADBACKEGLWINDOW_H
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
new file mode 100644
index 0000000000..0d8e01b6bb
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
@@ -0,0 +1,14 @@
+
+LIBS += -lX11 -lXext -lEGL
+
+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
new file mode 100644
index 0000000000..08c5cf6c51
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.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$
+** 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 "qwaylandreadbackglxcontext.h"
+
+#include "qwaylandshmsurface.h"
+#include "qwaylandreadbackglxwindow.h"
+
+#include <QtCore/QDebug>
+
+static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
+{
+ const int width = img.width();
+ const int height = img.height();
+
+ if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
+ || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
+ {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
+ }
+ } else {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
+ }
+ }
+}
+
+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)
+{
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
+ mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+
+ geometryChanged();
+}
+
+void QWaylandReadbackGlxContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+
+ glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext);
+}
+
+void QWaylandReadbackGlxContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+}
+
+void QWaylandReadbackGlxContext::swapBuffers()
+{
+ if (QPlatformGLContext::currentContext() != this) {
+ makeCurrent();
+ }
+
+ QSize size = mWindow->geometry().size();
+
+ 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);
+
+ img = img.mirrored();
+ qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV);
+ constBits = img.bits();
+
+ const uchar *constDstBits = mBuffer->image()->bits();
+ uchar *dstBits = const_cast<uchar *>(constDstBits);
+ memcpy(dstBits,constBits,(img.width()*4) * img.height());
+
+
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+ mWindow->waitForFrameSync();
+
+}
+
+void * QWaylandReadbackGlxContext::getProcAddress(const QString &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 :(";
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
new file mode 100644
index 0000000000..5fafcf03bf
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 QWAYLANDREADBACKGLXCONTEXT_H
+#define QWAYLANDREADBACKGLXCONTEXT_H
+
+#include <QPlatformGLContext>
+
+#include "qwaylandreadbackglxintegration.h"
+
+#include "qglxconvenience.h"
+
+class QWaylandReadbackGlxWindow;
+class QWaylandShmBuffer;
+
+class QWaylandReadbackGlxContext : public QPlatformGLContext
+{
+public:
+ QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window);
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandReadbackGlxIntegration *mGlxIntegration;
+ QWaylandReadbackGlxWindow *mWindow;
+ QWaylandShmBuffer *mBuffer;
+
+ Pixmap mPixmap;
+ GLXFBConfig mConfig;
+ GLXContext mContext;
+ GLXPixmap mGlxPixmap;
+};
+
+#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
new file mode 100644
index 0000000000..4651f0c30e
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
@@ -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$
+** 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 "qwaylandreadbackglxintegration.h"
+
+#include "qwaylandreadbackglxwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandReadbackGlxIntegration::QWaylandReadbackGlxIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
+{
+ qDebug() << "Using Readback-GLX";
+ char *display_name = getenv("DISPLAY");
+ mDisplay = XOpenDisplay(display_name);
+ mScreen = XDefaultScreen(mDisplay);
+ mRootWindow = XDefaultRootWindow(mDisplay);
+ XSync(mDisplay, False);
+}
+
+QWaylandReadbackGlxIntegration::~QWaylandReadbackGlxIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+void QWaylandReadbackGlxIntegration::initialize()
+{
+}
+
+QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandReadbackGlxWindow(widget,this);
+}
+
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandReadbackGlxIntegration(waylandDisplay);
+}
+
+Display * QWaylandReadbackGlxIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+int QWaylandReadbackGlxIntegration::screen() const
+{
+ return mScreen;
+}
+
+Window QWaylandReadbackGlxIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+QWaylandDisplay * QWaylandReadbackGlxIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
new file mode 100644
index 0000000000..9056393905
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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 QWAYLANDREADBACKGLXINTEGRATION_H
+#define QWAYLANDREADBACKGLXINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <X11/Xlib.h>
+
+class QWaylandReadbackGlxIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandReadbackGlxIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandReadbackGlxIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+
+ Display *xDisplay() const;
+ int screen() const;
+ Window rootWindow() const;
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+
+ Display *mDisplay;
+ int mScreen;
+ Window mRootWindow;
+
+};
+
+#endif // QWAYLANDREADBACKGLXINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
new file mode 100644
index 0000000000..ca1603c649
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 "qwaylandreadbackglxwindow.h"
+
+QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration)
+ : QWaylandShmWindow(window)
+ , mGlxIntegration(glxIntegration)
+ , mContext(0)
+{
+}
+
+QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const
+{
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext * QWaylandReadbackGlxWindow::glContext() const
+{
+ if (!mContext) {
+ QWaylandReadbackGlxWindow *that = const_cast<QWaylandReadbackGlxWindow *>(this);
+ that->mContext = new QWaylandReadbackGlxContext(mGlxIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
+{
+ QWaylandShmWindow::setGeometry(rect);
+
+ if (mContext) {
+ mContext->geometryChanged();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
new file mode 100644
index 0000000000..4d7bb3ee74
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 QWAYLANDREADBACKGLXWINDOW_H
+#define QWAYLANDREADBACKGLXWINDOW_H
+
+#include "qwaylandshmwindow.h"
+#include "qwaylandreadbackglxintegration.h"
+#include "qwaylandreadbackglxcontext.h"
+
+class QWaylandReadbackGlxWindow : public QWaylandShmWindow
+{
+public:
+ QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration);
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandReadbackGlxIntegration *mGlxIntegration;
+ QWaylandReadbackGlxContext *mContext;
+
+};
+
+#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
new file mode 100644
index 0000000000..f8ea005937
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
@@ -0,0 +1,12 @@
+include (../../../glxconvenience/glxconvenience.pri)
+HEADERS += \
+ $$PWD/qwaylandreadbackglxintegration.h \
+ $$PWD/qwaylandreadbackglxwindow.h \
+ $$PWD/qwaylandreadbackglxcontext.h
+
+SOURCES += \
+ $$PWD/qwaylandreadbackglxintegration.cpp \
+ $$PWD/qwaylandreadbackglxwindow.cpp \
+ $$PWD/qwaylandreadbackglxcontext.cpp
+
+LIBS += -lX11
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h
new file mode 100644
index 0000000000..5dc2addd10
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** 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 QWAYLANDEGLINCLUDE_H
+#define QWAYLANDEGLINCLUDE_H
+
+#include <wayland-client.h>
+
+#include <wayland-egl.h>
+
+#define GL_GLEXT_PROTOTYPES
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#endif // QWAYLANDEGLINCLUDE_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
new file mode 100644
index 0000000000..39e7be5ac6
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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 "qwaylandeglintegration.h"
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include "qwaylandeglwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay)
+ : mWaylandDisplay(waylandDisplay)
+ , mNativeEglDisplay(wl_egl_display_create(mWaylandDisplay))
+{
+ qDebug() << "Using Wayland-EGL";
+}
+
+
+QWaylandEglIntegration::~QWaylandEglIntegration()
+{
+ eglTerminate(mEglDisplay);
+}
+
+void QWaylandEglIntegration::initialize()
+{
+ EGLint major,minor;
+ mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay);
+ if (mEglDisplay == NULL) {
+ qWarning("EGL not available");
+ } else {
+ if (!eglInitialize(mEglDisplay, &major, &minor)) {
+ qWarning("failed to initialize EGL display");
+ return;
+ }
+ }
+}
+
+QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWidget *window)
+{
+ return new QWaylandEglWindow(window);
+}
+
+EGLDisplay QWaylandEglIntegration::eglDisplay() const
+{
+ return mEglDisplay;
+}
+
+wl_egl_display * QWaylandEglIntegration::nativeDisplay() const
+{
+ return mNativeEglDisplay;
+}
+
+QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandEglIntegration(waylandDisplay->wl_display());
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
new file mode 100644
index 0000000000..bf4c3fe45c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 QWAYLANDEGLINTEGRATION_H
+#define QWAYLANDEGLINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include "qwaylandeglinclude.h"
+
+class QWaylandWindow;
+class QWidget;
+
+class QWaylandEglIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandEglIntegration(struct wl_display *waylandDisplay);
+ ~QWaylandEglIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *window);
+
+ EGLDisplay eglDisplay() const;
+ struct wl_egl_display *nativeDisplay() const;
+private:
+ struct wl_display *mWaylandDisplay;
+
+ EGLDisplay mEglDisplay;
+ struct wl_egl_display *mNativeEglDisplay;
+
+
+};
+
+#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
new file mode 100644
index 0000000000..d7cf0a55e1
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 "qwaylandeglwindow.h"
+
+#include "qwaylandscreen.h"
+#include "qwaylandglcontext.h"
+
+QWaylandEglWindow::QWaylandEglWindow(QWidget *window)
+ : QWaylandWindow(window)
+ , mGLContext(0)
+ , mWaylandEglWindow(0)
+{
+ mEglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration());
+ //super creates a new surface
+ newSurfaceCreated();
+}
+
+QWaylandEglWindow::~QWaylandEglWindow()
+{
+ delete mGLContext;
+}
+
+QWaylandWindow::WindowType QWaylandEglWindow::windowType() const
+{
+ return QWaylandWindow::Egl;
+}
+
+void QWaylandEglWindow::setGeometry(const QRect &rect)
+{
+ QWaylandWindow::setGeometry(rect);
+ if (mWaylandEglWindow) {
+ wl_egl_window_resize(mWaylandEglWindow,rect.width(),rect.height(),0,0);
+ }
+}
+
+void QWaylandEglWindow::setParent(const QPlatformWindow *parent)
+{
+ const QWaylandWindow *wParent = static_cast<const QWaylandWindow *>(parent);
+
+ mParentWindow = wParent;
+}
+
+QPlatformGLContext * QWaylandEglWindow::glContext() const
+{
+ if (!mGLContext) {
+ QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this);
+ that->mGLContext = new QWaylandGLContext(mEglIntegration->eglDisplay(),widget()->platformWindowFormat());
+
+ EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
+ EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
+ that->mGLContext->setEglSurface(surface);
+ }
+
+ return mGLContext;
+}
+
+void QWaylandEglWindow::newSurfaceCreated()
+{
+ 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);
+
+ mWaylandEglWindow = wl_egl_window_create(mEglIntegration->nativeDisplay(),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);
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
new file mode 100644
index 0000000000..549d039bf8
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.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$
+** 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 QWAYLANDEGLWINDOW_H
+#define QWAYLANDEGLWINDOW_H
+
+#include "qwaylandwindow.h"
+#include "qwaylandeglinclude.h"
+#include "qwaylandeglintegration.h"
+
+class QWaylandGLContext;
+
+class QWaylandEglWindow : public QWaylandWindow
+{
+public:
+ QWaylandEglWindow(QWidget *window);
+ ~QWaylandEglWindow();
+ WindowType windowType() const;
+ void setGeometry(const QRect &rect);
+ void setParent(const QPlatformWindow *parent);
+ QPlatformGLContext *glContext() const;
+protected:
+ void newSurfaceCreated();
+private:
+ QWaylandEglIntegration *mEglIntegration;
+ QWaylandGLContext *mGLContext;
+ struct wl_egl_window *mWaylandEglWindow;
+ EGLConfig mConfig;
+
+ const QWaylandWindow *mParentWindow;
+};
+
+#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
new file mode 100644
index 0000000000..d293019909
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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 "qwaylandglcontext.h"
+
+#include "qwaylanddisplay.h"
+#include "qwaylandwindow.h"
+
+#include "../../../eglconvenience/qeglconvenience.h"
+
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformWindowFormat>
+#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))
+{
+ QPlatformGLContext *sharePlatformContext = 0;
+ sharePlatformContext = format.sharedGLContext();
+ mFormat.setSharedContext(sharePlatformContext);
+ EGLContext shareEGLContext = EGL_NO_CONTEXT;
+ if (sharePlatformContext)
+ shareEGLContext = static_cast<const QWaylandGLContext*>(sharePlatformContext)->mContext;
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+
+ QVector<EGLint> eglContextAttrs;
+ eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ eglContextAttrs.append(2);
+ eglContextAttrs.append(EGL_NONE);
+
+ mContext = eglCreateContext(mEglDisplay, mConfig,
+ shareEGLContext, eglContextAttrs.constData());
+}
+
+QWaylandGLContext::QWaylandGLContext()
+ : QPlatformGLContext()
+ , mEglDisplay(0)
+ , mContext(EGL_NO_CONTEXT)
+ , mSurface(EGL_NO_SURFACE)
+ , mConfig(0)
+{ }
+
+QWaylandGLContext::~QWaylandGLContext()
+{
+ eglDestroyContext(mEglDisplay,mContext);
+}
+
+void QWaylandGLContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+ if (mSurface == EGL_NO_SURFACE) {
+ qWarning("makeCurrent with EGL_NO_SURFACE");
+ }
+ eglMakeCurrent(mEglDisplay, mSurface, mSurface, mContext);
+}
+
+void QWaylandGLContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+}
+
+void QWaylandGLContext::swapBuffers()
+{
+ eglSwapBuffers(mEglDisplay,mSurface);
+}
+
+void *QWaylandGLContext::getProcAddress(const QString &string)
+{
+ return (void *) eglGetProcAddress(string.toLatin1().data());
+}
+
+void QWaylandGLContext::setEglSurface(EGLSurface surface)
+{
+ doneCurrent();
+ mSurface = surface;
+}
+
+EGLConfig QWaylandGLContext::eglConfig() const
+{
+ return mConfig;
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
new file mode 100644
index 0000000000..76caffabfb
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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 QWAYLANDGLCONTEXT_H
+#define QWAYLANDGLCONTEXT_H
+
+#include "qwaylanddisplay.h"
+
+#include <QtGui/QPlatformGLContext>
+
+#include "qwaylandeglinclude.h"
+
+class QWaylandWindow;
+class QWaylandGLWindowSurface;
+
+class QWaylandGLContext : public QPlatformGLContext {
+public:
+ QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format);
+ ~QWaylandGLContext();
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString&);
+
+ QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
+
+ void setEglSurface(EGLSurface surface);
+ EGLConfig eglConfig() const;
+private:
+ EGLDisplay mEglDisplay;
+
+ EGLContext mContext;
+ EGLSurface mSurface;
+ EGLConfig mConfig;
+ QPlatformWindowFormat mFormat;
+
+ QWaylandGLContext();
+
+};
+
+
+#endif // QWAYLANDGLCONTEXT_H
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
new file mode 100644
index 0000000000..bc978645c4
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
@@ -0,0 +1,12 @@
+LIBS += -lwayland-egl -lEGL
+INCLUDEPATH += $$PWD
+SOURCES += $$PWD/qwaylandeglintegration.cpp \
+ $$PWD/qwaylandglcontext.cpp \
+ $$PWD/qwaylandeglwindow.cpp \
+ $$PWD/../../../eglconvenience/qeglconvenience.cpp
+
+HEADERS += $$PWD/qwaylandeglintegration.h \
+ $$PWD/qwaylandglcontext.h \
+ $$PWD/qwaylandeglwindow.h \
+ $$PWD/../../../eglconvenience/qeglconvenience.h \
+ gl_integration/wayland_egl/qwaylandeglinclude.h
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
new file mode 100644
index 0000000000..92acf752e4
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** 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 "qwaylandxcompositeeglcontext.h"
+
+#include "qwaylandxcompositeeglwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+#include <QtCore/QDebug>
+
+#include "qeglconvenience.h"
+#include "qxlibeglintegration.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()
+{
+ QPlatformGLContext::doneCurrent();
+ eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+}
+
+void QWaylandXCompositeEGLContext::swapBuffers()
+{
+ QSize size = mWindow->geometry().size();
+
+ eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface);
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+ mWindow->waitForFrameSync();
+}
+
+void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName)
+{
+ return (void *)eglGetProcAddress(qPrintable(procName));
+}
+
+QPlatformWindowFormat QWaylandXCompositeEGLContext::platformWindowFormat() const
+{
+ return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+}
+
+void QWaylandXCompositeEGLContext::sync_function(void *data)
+{
+ 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();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
new file mode 100644
index 0000000000..f0693d4d81
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.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$
+** 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 QWAYLANDXCOMPOSITEEGLCONTEXT_H
+#define QWAYLANDXCOMPOSITEEGLCONTEXT_H
+
+#include <QtGui/QPlatformGLContext>
+
+#include <QtCore/QWaitCondition>
+
+#include "qwaylandbuffer.h"
+#include "qwaylandxcompositeeglintegration.h"
+
+class QWaylandXCompositeEGLWindow;
+
+class QWaylandXCompositeEGLContext : public QPlatformGLContext
+{
+public:
+ QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window);
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandXCompositeEGLIntegration *mEglIntegration;
+ QWaylandXCompositeEGLWindow *mWindow;
+ QWaylandBuffer *mBuffer;
+
+ Window mXWindow;
+ EGLConfig mConfig;
+ EGLContext mContext;
+ EGLSurface mEglWindowSurface;
+
+ static void sync_function(void *data);
+ bool mWaitingForSync;
+};
+
+#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
new file mode 100644
index 0000000000..95b4112cdc
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.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$
+** 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 "qwaylandxcompositeeglintegration.h"
+
+#include "qwaylandxcompositeeglwindow.h"
+
+#include <QtCore/QDebug>
+
+#include "wayland-xcomposite-client-protocol.h"
+
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandXCompositeEGLIntegration(waylandDisplay);
+}
+
+QWaylandXCompositeEGLIntegration::QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
+{
+ qDebug() << "Using XComposite-EGL";
+ wl_display_add_global_listener(mWaylandDisplay->wl_display(), QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal,
+ this);
+}
+
+QWaylandXCompositeEGLIntegration::~QWaylandXCompositeEGLIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+void QWaylandXCompositeEGLIntegration::initialize()
+{
+}
+
+QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandXCompositeEGLWindow(widget,this);
+}
+
+Display * QWaylandXCompositeEGLIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+EGLDisplay QWaylandXCompositeEGLIntegration::eglDisplay() const
+{
+ return mEglDisplay;
+}
+
+int QWaylandXCompositeEGLIntegration::screen() const
+{
+ return mScreen;
+}
+
+Window QWaylandXCompositeEGLIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+QWaylandDisplay * QWaylandXCompositeEGLIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
+wl_xcomposite * QWaylandXCompositeEGLIntegration::waylandXComposite() const
+{
+ return mWaylandComposite;
+}
+
+const struct wl_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite_listener = {
+ QWaylandXCompositeEGLIntegration::rootInformation
+};
+
+void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
+{
+ Q_UNUSED(version);
+ if (strcmp(interface, "xcomposite") == 0) {
+ QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data);
+ integration->mWaylandComposite = wl_xcomposite_create(display,id);
+ wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
+ }
+
+}
+
+void QWaylandXCompositeEGLIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window)
+{
+ Q_UNUSED(xcomposite);
+ QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data);
+
+ integration->mDisplay = XOpenDisplay(display_name);
+ integration->mRootWindow = (Window) root_window;
+ integration->mScreen = XDefaultScreen(integration->mDisplay);
+ integration->mEglDisplay = eglGetDisplay(integration->mDisplay);
+ eglBindAPI(EGL_OPENGL_ES_API);
+ EGLint minor,major;
+ if (!eglInitialize(integration->mEglDisplay,&major,&minor)) {
+ qFatal("Failed to initialize EGL");
+ }
+ eglSwapInterval(integration->eglDisplay(),0);
+ qDebug() << "ROOT INFORMATION" << integration->mDisplay << integration->mRootWindow << integration->mScreen;
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
new file mode 100644
index 0000000000..590ae3754c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** 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 QWAYLANDXCOMPOSITEEGLINTEGRATION_H
+#define QWAYLANDXCOMPOSITEEGLINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+#include "wayland-client.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <QWaitCondition>
+
+#include <X11/Xlib.h>
+#include <EGL/egl.h>
+
+struct wl_xcomposite;
+
+class QWaylandXCompositeEGLIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandXCompositeEGLIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+ struct wl_xcomposite *waylandXComposite() const;
+
+ Display *xDisplay() const;
+ EGLDisplay eglDisplay() const;
+ int screen() const;
+ Window rootWindow() const;
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ struct wl_xcomposite *mWaylandComposite;
+
+ Display *mDisplay;
+ EGLDisplay mEglDisplay;
+ int mScreen;
+ Window mRootWindow;
+
+ static void wlDisplayHandleGlobal(struct wl_display *display, uint32_t id,
+ const char *interface, uint32_t version, void *data);
+
+ static const struct wl_xcomposite_listener xcomposite_listener;
+ static void rootInformation(void *data,
+ struct wl_xcomposite *xcomposite,
+ const char *display_name,
+ uint32_t root_window);
+};
+
+#endif // QWAYLANDXCOMPOSITEEGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
new file mode 100644
index 0000000000..1c9d36fe92
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 "qwaylandxcompositeeglwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration)
+ : QWaylandWindow(window)
+ , mGlxIntegration(glxIntegration)
+ , mContext(0)
+{
+
+}
+
+QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
+{
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const
+{
+ if (!mContext) {
+ qDebug() << "creating glcontext;";
+ QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this);
+ that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
+{
+ QWaylandWindow::setGeometry(rect);
+
+ if (mContext) {
+ mContext->geometryChanged();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
new file mode 100644
index 0000000000..fc33b32322
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 QWAYLANDXCOMPOSITEEGLWINDOW_H
+#define QWAYLANDXCOMPOSITEEGLWINDOW_H
+
+#include "qwaylandwindow.h"
+#include "qwaylandxcompositeeglintegration.h"
+#include "qwaylandxcompositeeglcontext.h"
+
+class QWaylandXCompositeEGLWindow : public QWaylandWindow
+{
+public:
+ QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration);
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandXCompositeEGLIntegration *mGlxIntegration;
+ QWaylandXCompositeEGLContext *mContext;
+
+};
+
+#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
new file mode 100644
index 0000000000..c3533f9ce3
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
@@ -0,0 +1,15 @@
+include (../xcomposite_share/xcomposite_share.pri)
+include (../../../eglconvenience/eglconvenience.pri)
+include (../../../eglconvenience/xlibeglintegration.pri)
+
+LIBS += -lXcomposite -lEGL
+
+SOURCES += \
+ $$PWD/qwaylandxcompositeeglcontext.cpp \
+ $$PWD/qwaylandxcompositeeglintegration.cpp \
+ $$PWD/qwaylandxcompositeeglwindow.cpp
+
+HEADERS += \
+ $$PWD/qwaylandxcompositeeglcontext.h \
+ $$PWD/qwaylandxcompositeeglintegration.h \
+ $$PWD/qwaylandxcompositeeglwindow.h
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
new file mode 100644
index 0000000000..caf51170a6
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** 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 "qwaylandxcompositeglxcontext.h"
+
+#include "qwaylandxcompositeglxwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+#include <QtCore/QDebug>
+
+#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)
+{
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
+ mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+
+ geometryChanged();
+}
+
+void QWaylandXCompositeGLXContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+ glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext);
+}
+
+void QWaylandXCompositeGLXContext::doneCurrent()
+{
+ glXMakeCurrent(mGlxIntegration->xDisplay(),0,0);
+ QPlatformGLContext::doneCurrent();
+}
+
+void QWaylandXCompositeGLXContext::swapBuffers()
+{
+ QSize size = mWindow->geometry().size();
+
+ glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow);
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+ mWindow->waitForFrameSync();
+}
+
+void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName)
+{
+ return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
+}
+
+QPlatformWindowFormat QWaylandXCompositeGLXContext::platformWindowFormat() const
+{
+ return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
+}
+
+void QWaylandXCompositeGLXContext::sync_function(void *data)
+{
+ QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data);
+ that->mWaitingForSyncCallback = false;
+}
+
+void QWaylandXCompositeGLXContext::waitForSync()
+{
+ 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();
+ }
+}
+
+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.colormap = cmap;
+ mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ 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
new file mode 100644
index 0000000000..eb2e5a518e
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 QWAYLANDXCOMPOSITEGLXCONTEXT_H
+#define QWAYLANDXCOMPOSITEGLXCONTEXT_H
+
+#include <QtGui/QPlatformGLContext>
+
+#include <QtCore/QWaitCondition>
+
+#include "qwaylandbuffer.h"
+#include "qwaylandxcompositeglxintegration.h"
+
+#include "qglxconvenience.h"
+
+class QWaylandXCompositeGLXWindow;
+class QWaylandShmBuffer;
+
+class QWaylandXCompositeGLXContext : public QPlatformGLContext
+{
+public:
+ QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window);
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandXCompositeGLXIntegration *mGlxIntegration;
+ QWaylandXCompositeGLXWindow *mWindow;
+ QWaylandBuffer *mBuffer;
+
+ Window mXWindow;
+ GLXFBConfig mConfig;
+ GLXContext mContext;
+
+ static void sync_function(void *data);
+ void waitForSync();
+ bool mWaitingForSyncCallback;
+};
+
+#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
new file mode 100644
index 0000000000..43c0135c6e
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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 "qwaylandxcompositeglxintegration.h"
+
+#include "qwaylandxcompositeglxwindow.h"
+
+#include <QtCore/QDebug>
+
+#include "wayland-xcomposite-client-protocol.h"
+
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandXCompositeGLXIntegration(waylandDisplay);
+}
+
+QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
+{
+ qDebug() << "Using XComposite-GLX";
+ wl_display_add_global_listener(waylandDispaly->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal,
+ this);
+}
+
+QWaylandXCompositeGLXIntegration::~QWaylandXCompositeGLXIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+void QWaylandXCompositeGLXIntegration::initialize()
+{
+}
+
+QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandXCompositeGLXWindow(widget,this);
+}
+
+Display * QWaylandXCompositeGLXIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+int QWaylandXCompositeGLXIntegration::screen() const
+{
+ return mScreen;
+}
+
+Window QWaylandXCompositeGLXIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+QWaylandDisplay * QWaylandXCompositeGLXIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
+wl_xcomposite * QWaylandXCompositeGLXIntegration::waylandXComposite() const
+{
+ return mWaylandComposite;
+}
+
+const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite_listener = {
+ QWaylandXCompositeGLXIntegration::rootInformation
+};
+
+void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
+{
+ Q_UNUSED(version);
+ if (strcmp(interface, "xcomposite") == 0) {
+ QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
+ integration->mWaylandComposite = wl_xcomposite_create(display,id);
+ wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
+ }
+
+}
+
+void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window)
+{
+ Q_UNUSED(xcomposite);
+ QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
+
+ 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
new file mode 100644
index 0000000000..24a40167e2
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QWAYLANDXCOMPOSITEGLXINTEGRATION_H
+#define QWAYLANDXCOMPOSITEGLXINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+#include "wayland-client.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <X11/Xlib.h>
+
+struct wl_xcomposite;
+
+class QWaylandXCompositeGLXIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandXCompositeGLXIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+ struct wl_xcomposite *waylandXComposite() const;
+
+ Display *xDisplay() const;
+ int screen() const;
+ Window rootWindow() const;
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ struct wl_xcomposite *mWaylandComposite;
+
+ Display *mDisplay;
+ int mScreen;
+ Window mRootWindow;
+
+ static void wlDisplayHandleGlobal(struct wl_display *display, uint32_t id,
+ const char *interface, uint32_t version, void *data);
+
+ static const struct wl_xcomposite_listener xcomposite_listener;
+ static void rootInformation(void *data,
+ struct wl_xcomposite *xcomposite,
+ const char *display_name,
+ uint32_t root_window);
+};
+
+#endif // QWAYLANDXCOMPOSITEGLXINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
new file mode 100644
index 0000000000..db0f254a20
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 "qwaylandxcompositeglxwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration)
+ : QWaylandWindow(window)
+ , mGlxIntegration(glxIntegration)
+ , mContext(0)
+{
+
+}
+
+QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
+{
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext * QWaylandXCompositeGLXWindow::glContext() const
+{
+ if (!mContext) {
+ qDebug() << "creating glcontext;";
+ QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this);
+ that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
+{
+ QWaylandWindow::setGeometry(rect);
+
+ if (mContext) {
+ mContext->geometryChanged();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
new file mode 100644
index 0000000000..536153dbcf
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 QWAYLANDXCOMPOSITEGLXWINDOW_H
+#define QWAYLANDXCOMPOSITEGLXWINDOW_H
+
+#include "qwaylandwindow.h"
+#include "qwaylandxcompositeglxintegration.h"
+#include "qwaylandxcompositeglxcontext.h"
+
+class QWaylandXCompositeGLXWindow : public QWaylandWindow
+{
+public:
+ QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration);
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandXCompositeGLXIntegration *mGlxIntegration;
+ QWaylandXCompositeGLXContext *mContext;
+
+};
+
+#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
new file mode 100644
index 0000000000..43295e91e7
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
@@ -0,0 +1,13 @@
+include (../xcomposite_share/xcomposite_share.pri)
+include (../../../glxconvenience/glxconvenience.pri)
+
+LIBS += -lXcomposite
+SOURCES += \
+ $$PWD/qwaylandxcompositeglxcontext.cpp \
+ $$PWD/qwaylandxcompositeglxintegration.cpp \
+ $$PWD/qwaylandxcompositeglxwindow.cpp
+
+HEADERS += \
+ $$PWD/qwaylandxcompositeglxcontext.h \
+ $$PWD/qwaylandxcompositeglxintegration.h \
+ $$PWD/qwaylandxcompositeglxwindow.h
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
new file mode 100644
index 0000000000..4b0d3a073f
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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 "qwaylandxcompositebuffer.h"
+
+#include "wayland-client.h"
+
+QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(wl_xcomposite *xcomposite, uint32_t window, const QSize &size, wl_visual *visual)
+ :mSize(size)
+{
+ mBuffer = wl_xcomposite_create_buffer(xcomposite,
+ window,
+ size.width(),
+ size.height(),
+ visual);
+}
+
+QSize QWaylandXCompositeBuffer::size() const
+{
+ return mSize;
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
new file mode 100644
index 0000000000..b346651957
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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 QWAYLANDXCOMPOSITEBUFFER_H
+#define QWAYLANDXCOMPOSITEBUFFER_H
+
+#include "qwaylandbuffer.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+
+class QWaylandXCompositeBuffer : public QWaylandBuffer
+{
+public:
+ QWaylandXCompositeBuffer(struct wl_xcomposite *xcomposite,
+ uint32_t window,
+ const QSize &size,
+ struct wl_visual *visual);
+
+ QSize size() const;
+private:
+ QSize mSize;
+};
+
+#endif // QWAYLANDXCOMPOSITEBUFFER_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h
new file mode 100644
index 0000000000..72376e1dcb
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h
@@ -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$
+** 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 XCOMPOSITE_CLIENT_PROTOCOL_H
+#define XCOMPOSITE_CLIENT_PROTOCOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+
+struct wl_client;
+
+struct wl_xcomposite;
+
+struct wl_proxy;
+
+extern void
+wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
+extern struct wl_proxy *
+wl_proxy_create(struct wl_proxy *factory,
+ const struct wl_interface *interface);
+extern struct wl_proxy *
+wl_proxy_create_for_id(struct wl_display *display,
+ const struct wl_interface *interface, uint32_t id);
+extern void
+wl_proxy_destroy(struct wl_proxy *proxy);
+
+extern int
+wl_proxy_add_listener(struct wl_proxy *proxy,
+ void (**implementation)(void), void *data);
+
+extern void
+wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);
+
+extern void *
+wl_proxy_get_user_data(struct wl_proxy *proxy);
+
+extern const struct wl_interface wl_xcomposite_interface;
+
+struct wl_xcomposite_listener {
+ void (*root)(void *data,
+ struct wl_xcomposite *xcomposite,
+ const char *display_name,
+ uint32_t root_window);
+};
+
+static inline int
+wl_xcomposite_add_listener(struct wl_xcomposite *xcomposite,
+ const struct wl_xcomposite_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) xcomposite,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_XCOMPOSITE_CREATE_BUFFER 0
+
+static inline struct wl_xcomposite *
+wl_xcomposite_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_xcomposite *)
+ wl_proxy_create_for_id(display, &wl_xcomposite_interface, id);
+}
+
+static inline void
+wl_xcomposite_set_user_data(struct wl_xcomposite *xcomposite, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) xcomposite, user_data);
+}
+
+static inline void *
+wl_xcomposite_get_user_data(struct wl_xcomposite *xcomposite)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) xcomposite);
+}
+
+static inline void
+wl_xcomposite_destroy(struct wl_xcomposite *xcomposite)
+{
+ wl_proxy_destroy((struct wl_proxy *) xcomposite);
+}
+
+static inline struct wl_buffer *
+wl_xcomposite_create_buffer(struct wl_xcomposite *xcomposite, uint32_t x_window, int width, int height, struct wl_visual *visual)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) xcomposite,
+ &wl_buffer_interface);
+ if (!id)
+ return NULL;
+
+ wl_proxy_marshal((struct wl_proxy *) xcomposite,
+ WL_XCOMPOSITE_CREATE_BUFFER, id, x_window, width, height, visual);
+
+ return (struct wl_buffer *) id;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c
new file mode 100644
index 0000000000..5c966fda46
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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 <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+static const struct wl_message xcomposite_requests[] = {
+ { "create_buffer", "nuiio" },
+};
+
+static const struct wl_message xcomposite_events[] = {
+ { "root", "su" },
+};
+
+WL_EXPORT const struct wl_interface wl_xcomposite_interface = {
+ "xcomposite", 1,
+ ARRAY_LENGTH(xcomposite_requests), xcomposite_requests,
+ ARRAY_LENGTH(xcomposite_events), xcomposite_events,
+};
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri
new file mode 100644
index 0000000000..03b3521e86
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri
@@ -0,0 +1,9 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/wayland-xcomposite-client-protocol.h \
+ gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
+
+SOURCES += \
+ $$PWD/wayland-xcomposite-protocol.c \
+ gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
diff --git a/src/plugins/platforms/wayland/main.cpp b/src/plugins/platforms/wayland/main.cpp
new file mode 100644
index 0000000000..6dc1c2b1ae
--- /dev/null
+++ b/src/plugins/platforms/wayland/main.cpp
@@ -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$
+** 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 <QtGui/QPlatformIntegrationPlugin>
+#include "qwaylandintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QWaylandIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "Wayland";
+ list << "WaylandGL";
+ return list;
+}
+
+QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "wayland")
+ return new QWaylandIntegration;
+ if (system.toLower() == "waylandgl")
+ return new QWaylandIntegration(true);
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(wayland, QWaylandIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandbuffer.h b/src/plugins/platforms/wayland/qwaylandbuffer.h
new file mode 100644
index 0000000000..8779d5fda0
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandbuffer.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 QWAYLANDBUFFER_H
+#define QWAYLANDBUFFER_H
+
+#include <QtCore/QSize>
+
+#include <wayland-client-protocol.h>
+
+class QWaylandBuffer {
+public:
+ QWaylandBuffer() { }
+ virtual ~QWaylandBuffer() { }
+ wl_buffer *buffer() {return mBuffer;}
+ virtual QSize size() const = 0;
+
+protected:
+ struct wl_buffer *mBuffer;
+};
+
+#endif // QWAYLANDBUFFER_H
diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp
new file mode 100644
index 0000000000..614686f971
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** 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 "qwaylandcursor.h"
+
+#include "qwaylanddisplay.h"
+#include "qwaylandinputdevice.h"
+#include "qwaylandshmsurface.h"
+#include "qwaylandscreen.h"
+
+#include <QtGui/QImageReader>
+
+#define DATADIR "/usr/share"
+
+static const struct pointer_image {
+ const char *filename;
+ int hotspot_x, hotspot_y;
+} pointer_images[] = {
+ /* FIXME: Half of these are wrong... */
+ /* Qt::ArrowCursor */
+ { DATADIR "/wayland/left_ptr.png", 10, 5 },
+ /* Qt::UpArrowCursor */
+ { DATADIR "/wayland/top_side.png", 18, 8 },
+ /* Qt::CrossCursor */
+ { DATADIR "/wayland/top_side.png", 18, 8 },
+ /* Qt::WaitCursor */
+ { DATADIR "/wayland/top_side.png", 18, 8 },
+ /* Qt::IBeamCursor */
+ { DATADIR "/wayland/xterm.png", 15, 15 },
+ /* Qt::SizeVerCursor */
+ { DATADIR "/wayland/top_side.png", 18, 8 },
+ /* Qt::SizeHorCursor */
+ { DATADIR "/wayland/bottom_left_corner.png", 6, 30 },
+ /* Qt::SizeBDiagCursor */
+ { DATADIR "/wayland/bottom_right_corner.png", 28, 28 },
+ /* Qt::SizeFDiagCursor */
+ { DATADIR "/wayland/bottom_side.png", 16, 20 },
+ /* Qt::SizeAllCursor */
+ { DATADIR "/wayland/left_side.png", 10, 20 },
+ /* Qt::BlankCursor */
+ { DATADIR "/wayland/right_side.png", 30, 19 },
+ /* Qt::SplitVCursor */
+ { DATADIR "/wayland/sb_v_double_arrow.png", 15, 15 },
+ /* Qt::SplitHCursor */
+ { DATADIR "/wayland/sb_h_double_arrow.png", 15, 15 },
+ /* Qt::PointingHandCursor */
+ { DATADIR "/wayland/hand2.png", 14, 8 },
+ /* Qt::ForbiddenCursor */
+ { DATADIR "/wayland/top_right_corner.png", 26, 8 },
+ /* Qt::WhatsThisCursor */
+ { DATADIR "/wayland/top_right_corner.png", 26, 8 },
+ /* Qt::BusyCursor */
+ { DATADIR "/wayland/top_right_corner.png", 26, 8 },
+ /* Qt::OpenHandCursor */
+ { DATADIR "/wayland/hand1.png", 18, 11 },
+ /* Qt::ClosedHandCursor */
+ { DATADIR "/wayland/grabbing.png", 20, 17 },
+ /* Qt::DragCopyCursor */
+ { DATADIR "/wayland/dnd-copy.png", 13, 13 },
+ /* Qt::DragMoveCursor */
+ { DATADIR "/wayland/dnd-move.png", 13, 13 },
+ /* Qt::DragLinkCursor */
+ { DATADIR "/wayland/dnd-link.png", 13, 13 },
+};
+
+QWaylandCursor::QWaylandCursor(QWaylandScreen *screen)
+ : QPlatformCursor(screen)
+ , mBuffer(0)
+ , mDisplay(screen->display())
+{
+}
+
+void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget)
+{
+ const struct pointer_image *p;
+
+ if (widget == NULL)
+ return;
+
+ p = NULL;
+
+ switch (cursor->shape()) {
+ case Qt::ArrowCursor:
+ p = &pointer_images[cursor->shape()];
+ break;
+ case Qt::UpArrowCursor:
+ case Qt::CrossCursor:
+ case Qt::WaitCursor:
+ break;
+ case Qt::IBeamCursor:
+ p = &pointer_images[cursor->shape()];
+ break;
+ case Qt::SizeVerCursor: /* 5 */
+ case Qt::SizeHorCursor:
+ case Qt::SizeBDiagCursor:
+ case Qt::SizeFDiagCursor:
+ case Qt::SizeAllCursor:
+ case Qt::BlankCursor: /* 10 */
+ break;
+ case Qt::SplitVCursor:
+ case Qt::SplitHCursor:
+ case Qt::PointingHandCursor:
+ p = &pointer_images[cursor->shape()];
+ break;
+ case Qt::ForbiddenCursor:
+ case Qt::WhatsThisCursor: /* 15 */
+ case Qt::BusyCursor:
+ break;
+ case Qt::OpenHandCursor:
+ case Qt::ClosedHandCursor:
+ case Qt::DragCopyCursor:
+ case Qt::DragMoveCursor: /* 20 */
+ case Qt::DragLinkCursor:
+ p = &pointer_images[cursor->shape()];
+ break;
+
+ default:
+ case Qt::BitmapCursor:
+ break;
+ }
+
+ if (!p) {
+ 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)
+ delete mBuffer;
+
+ mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(),
+ QImage::Format_ARGB32);
+ }
+
+ reader.read(mBuffer->image());
+
+ mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y);
+}
+
+void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y)
+{
+ /* Qt doesn't tell us which input device we should set the cursor
+ * for, so set it for all devices. */
+ for (int i = 0; i < mInputDevices.count(); i++) {
+ QWaylandInputDevice *inputDevice = mInputDevices.at(i);
+ inputDevice->attach(buffer, x, y);
+ }
+}
diff --git a/src/plugins/platforms/wayland/qwaylandcursor.h b/src/plugins/platforms/wayland/qwaylandcursor.h
new file mode 100644
index 0000000000..254cb9473a
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandcursor.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 QWAYLANDCURSOR_H
+#define QWAYLANDCURSOR_H
+
+#include <QtGui/QPlatformCursor>
+
+class QWaylandShmBuffer;
+class QWaylandDisplay;
+class QWaylandScreen;
+
+class QWaylandCursor : QPlatformCursor {
+public:
+ QWaylandCursor(QWaylandScreen *screen);
+
+ void changeCursor(QCursor *cursor, QWidget *widget);
+ QWaylandShmBuffer *mBuffer;
+ QWaylandDisplay *mDisplay;
+};
+
+#endif // QWAYLANDCURSOR_H
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
new file mode 100644
index 0000000000..1c56561904
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -0,0 +1,270 @@
+/****************************************************************************
+**
+** 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 "qwaylanddisplay.h"
+
+#include "qwaylandwindow.h"
+#include "qwaylandscreen.h"
+#include "qwaylandcursor.h"
+#include "qwaylandinputdevice.h"
+
+#ifdef QT_WAYLAND_GL_SUPPORT
+#include "gl_integration/qwaylandglintegration.h"
+#endif
+
+#include <QtCore/QAbstractEventDispatcher>
+#include <QtGui/QApplication>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+
+struct wl_surface *QWaylandDisplay::createSurface(void *handle)
+{
+ struct wl_surface * surface = wl_compositor_create_surface(mCompositor);
+ wl_surface_set_user_data(surface, handle);
+ return surface;
+}
+
+struct wl_buffer *QWaylandDisplay::createShmBuffer(int fd,
+ int width, int height,
+ uint32_t stride,
+ struct wl_visual *visual)
+{
+ return wl_shm_create_buffer(mShm, fd, width, height, stride, visual);
+}
+
+struct wl_visual *QWaylandDisplay::rgbVisual()
+{
+ return wl_display_get_rgb_visual(mDisplay);
+}
+
+struct wl_visual *QWaylandDisplay::argbVisual()
+{
+ return wl_display_get_argb_visual(mDisplay);
+}
+
+struct wl_visual *QWaylandDisplay::argbPremultipliedVisual()
+{
+ return wl_display_get_premultiplied_argb_visual(mDisplay);
+}
+
+#ifdef QT_WAYLAND_GL_SUPPORT
+QWaylandGLIntegration * QWaylandDisplay::eglIntegration()
+{
+ return mEglIntegration;
+}
+#endif
+
+void QWaylandDisplay::shellHandleConfigure(void *data, struct wl_shell *shell,
+ uint32_t time, uint32_t edges,
+ struct wl_surface *surface,
+ int32_t width, int32_t height)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(shell);
+ Q_UNUSED(time);
+ Q_UNUSED(edges);
+ QWaylandWindow *ww = (QWaylandWindow *) wl_surface_get_user_data(surface);
+
+ ww->configure(time, edges, 0, 0, width, height);
+}
+
+const struct wl_shell_listener QWaylandDisplay::shellListener = {
+ QWaylandDisplay::shellHandleConfigure,
+};
+
+QWaylandDisplay::QWaylandDisplay(void)
+{
+ mDisplay = wl_display_connect(NULL);
+ if (mDisplay == NULL) {
+ qErrnoWarning(errno, "Failed to create display");
+ qFatal("No wayland connection available.");
+ }
+
+ wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this);
+
+#ifdef QT_WAYLAND_GL_SUPPORT
+ mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
+#endif
+
+ qRegisterMetaType<uint32_t>("uint32_t");
+
+#ifdef QT_WAYLAND_GL_SUPPORT
+ 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();
+}
+
+QWaylandDisplay::~QWaylandDisplay(void)
+{
+ close(mFd);
+#ifdef QT_WAYLAND_GL_SUPPORT
+ delete mEglIntegration;
+#endif
+ wl_display_destroy(mDisplay);
+}
+
+void QWaylandDisplay::createNewScreen(struct wl_output *output, QRect geometry)
+{
+ QWaylandScreen *waylandScreen = new QWaylandScreen(this,output,geometry);
+ mScreens.append(waylandScreen);
+}
+
+void QWaylandDisplay::syncCallback(wl_display_sync_func_t func, void *data)
+{
+ wl_display_sync_callback(mDisplay, func, data);
+}
+
+void QWaylandDisplay::frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data)
+{
+ wl_display_frame_callback(mDisplay, surface, func, data);
+}
+
+void QWaylandDisplay::flushRequests()
+{
+ if (mSocketMask & WL_DISPLAY_WRITABLE)
+ wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
+}
+
+void QWaylandDisplay::readEvents()
+{
+// verify that there is still data on the socket
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(mFd, &fds);
+ fd_set nds;
+ FD_ZERO(&nds);
+ fd_set rs = fds;
+ fd_set ws = nds;
+ fd_set es = nds;
+ timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ int ret = ::select(mFd+1, &rs, &ws, &es, &timeout );
+
+ if (ret <= 0) {
+ //qDebug("QWaylandDisplay::readEvents() No data... blocking avoided");
+ return;
+ }
+
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+}
+
+void QWaylandDisplay::blockingReadEvents()
+{
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+}
+
+int QWaylandDisplay::sourceUpdate(uint32_t mask, void *data)
+{
+ QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
+ waylandDisplay->mSocketMask = mask;
+
+ return 0;
+}
+
+void QWaylandDisplay::outputHandleGeometry(void *data,
+ struct wl_output *output,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ //call back function called from another thread;
+ //but its safe to call createScreen from another thread since
+ //QWaylandScreen does a moveToThread
+ QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
+ QRect outputRect = QRect(x, y, width, height);
+ waylandDisplay->createNewScreen(output,outputRect);
+}
+
+const struct wl_output_listener QWaylandDisplay::outputListener = {
+ QWaylandDisplay::outputHandleGeometry
+};
+
+void QWaylandDisplay::waitForScreens()
+{
+ flushRequests();
+ while (mScreens.isEmpty())
+ blockingReadEvents();
+}
+
+void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version,
+ void *data)
+{
+ Q_UNUSED(display);
+ QWaylandDisplay *that = static_cast<QWaylandDisplay *>(data);
+ that->displayHandleGlobal(id, QByteArray(interface), version);
+}
+
+void QWaylandDisplay::displayHandleGlobal(uint32_t id,
+ const QByteArray &interface,
+ uint32_t version)
+{
+ Q_UNUSED(version);
+
+ if (interface == "output") {
+ struct wl_output *output = wl_output_create(mDisplay, id);
+ wl_output_add_listener(output, &outputListener, this);
+ } else if (interface == "compositor") {
+ mCompositor = wl_compositor_create(mDisplay, id);
+ } else if (interface == "shm") {
+ mShm = wl_shm_create(mDisplay, id);
+ } else if (interface == "shell"){
+ mShell = wl_shell_create(mDisplay, id);
+ wl_shell_add_listener(mShell, &shellListener, this);
+ } else if (interface == "input_device") {
+ QWaylandInputDevice *inputDevice =
+ new QWaylandInputDevice(mDisplay, id);
+ mInputDevices.append(inputDevice);
+ }
+}
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
new file mode 100644
index 0000000000..a2cb1b28ad
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** 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 QWAYLANDDISPLAY_H
+#define QWAYLANDDISPLAY_H
+
+#include <QtCore/QObject>
+#include <QtCore/QRect>
+
+#include <QtCore/QWaitCondition>
+
+#include <wayland-client.h>
+
+class QWaylandInputDevice;
+class QSocketNotifier;
+class QWaylandBuffer;
+class QPlatformScreen;
+class QWaylandScreen;
+class QWaylandGLIntegration;
+class QWaylandDisplay : public QObject {
+ Q_OBJECT
+
+public:
+ QWaylandDisplay(void);
+ ~QWaylandDisplay(void);
+
+ QList<QPlatformScreen *> screens() const { return mScreens; }
+ struct wl_surface *createSurface(void *handle);
+ struct wl_buffer *createShmBuffer(int fd, int width, int height,
+ uint32_t stride,
+ struct wl_visual *visual);
+ struct wl_visual *rgbVisual();
+ struct wl_visual *argbVisual();
+ struct wl_visual *argbPremultipliedVisual();
+
+#ifdef QT_WAYLAND_GL_SUPPORT
+ QWaylandGLIntegration *eglIntegration();
+#endif
+ void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y);
+
+ void syncCallback(wl_display_sync_func_t func, void *data);
+ void frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data);
+
+ struct wl_display *wl_display() const { return mDisplay; }
+
+ QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; }
+
+public slots:
+ void createNewScreen(struct wl_output *output, QRect geometry);
+ void readEvents();
+ void blockingReadEvents();
+ void flushRequests();
+
+private:
+ void waitForScreens();
+ void displayHandleGlobal(uint32_t id,
+ const QByteArray &interface,
+ uint32_t version);
+
+ struct wl_display *mDisplay;
+ struct wl_compositor *mCompositor;
+ struct wl_shm *mShm;
+ struct wl_shell *mShell;
+ QList<QPlatformScreen *> mScreens;
+ QList<QWaylandInputDevice *> mInputDevices;
+
+ QSocketNotifier *mReadNotifier;
+ int mFd;
+ bool mScreensInitialized;
+
+ uint32_t mSocketMask;
+
+ static const struct wl_output_listener outputListener;
+ static int sourceUpdate(uint32_t mask, void *data);
+ static void displayHandleGlobal(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version, void *data);
+ static void outputHandleGeometry(void *data,
+ struct wl_output *output,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+
+#ifdef QT_WAYLAND_GL_SUPPORT
+ QWaylandGLIntegration *mEglIntegration;
+#endif
+
+ static void shellHandleConfigure(void *data, struct wl_shell *shell,
+ uint32_t time, uint32_t edges,
+ struct wl_surface *surface,
+ int32_t width, int32_t height);
+
+ static const struct wl_shell_listener shellListener;
+};
+
+#endif // QWAYLANDDISPLAY_H
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
new file mode 100644
index 0000000000..6c2f341f64
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -0,0 +1,337 @@
+/****************************************************************************
+**
+** 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 "qwaylandinputdevice.h"
+
+#include "qwaylandintegration.h"
+#include "qwaylandwindow.h"
+#include "qwaylandbuffer.h"
+
+#include <QWindowSystemInterface>
+
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/QPlatformWindow>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifndef QT_NO_WAYLAND_XKB
+#include <X11/extensions/XKBcommon.h>
+#include <X11/keysym.h>
+#endif
+
+QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
+ uint32_t id)
+ : mDisplay(display)
+ , mInputDevice(wl_input_device_create(display, id))
+ , mPointerFocus(NULL)
+ , mKeyboardFocus(NULL)
+ , mButtons(0)
+{
+ wl_input_device_add_listener(mInputDevice,
+ &inputDeviceListener,
+ this);
+ wl_input_device_set_user_data(mInputDevice, this);
+
+#ifndef QT_NO_WAYLAND_XKB
+ struct xkb_rule_names names;
+ names.rules = "evdev";
+ names.model = "pc105";
+ names.layout = "us";
+ names.variant = "";
+ names.options = "";
+
+ mXkb = xkb_compile_keymap_from_rules(&names);
+#endif
+}
+
+void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
+{
+ if (window == mPointerFocus)
+ mPointerFocus = 0;
+ if (window == mKeyboardFocus)
+ mKeyboardFocus = 0;
+}
+
+void QWaylandInputDevice::inputHandleMotion(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ int32_t x, int32_t y,
+ int32_t surface_x, int32_t surface_y)
+{
+ Q_UNUSED(input_device);
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window = inputDevice->mPointerFocus;
+
+ inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
+ inputDevice->mGlobalPos = QPoint(x, y);
+ inputDevice->mTime = time;
+ QWindowSystemInterface::handleMouseEvent(window->widget(),
+ time,
+ inputDevice->mSurfacePos,
+ inputDevice->mGlobalPos,
+ inputDevice->mButtons);
+}
+
+void QWaylandInputDevice::inputHandleButton(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t button, uint32_t state)
+{
+ Q_UNUSED(input_device);
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window = inputDevice->mPointerFocus;
+ Qt::MouseButton qt_button;
+
+ switch (button) {
+ case 272:
+ qt_button = Qt::LeftButton;
+ break;
+ case 273:
+ qt_button = Qt::RightButton;
+ break;
+ case 274:
+ qt_button = Qt::MiddleButton;
+ break;
+ default:
+ return;
+ }
+
+ if (state)
+ inputDevice->mButtons |= qt_button;
+ else
+ inputDevice->mButtons &= ~qt_button;
+
+ inputDevice->mTime = time;
+ QWindowSystemInterface::handleMouseEvent(window->widget(),
+ time,
+ inputDevice->mSurfacePos,
+ inputDevice->mGlobalPos,
+ inputDevice->mButtons);
+}
+
+#ifndef QT_NO_WAYLAND_XKB
+static Qt::KeyboardModifiers translateModifiers(int s)
+{
+ const uchar qt_alt_mask = XKB_COMMON_MOD1_MASK;
+ const uchar qt_meta_mask = XKB_COMMON_MOD4_MASK;
+
+ Qt::KeyboardModifiers ret = 0;
+ if (s & XKB_COMMON_SHIFT_MASK)
+ ret |= Qt::ShiftModifier;
+ if (s & XKB_COMMON_CONTROL_MASK)
+ ret |= Qt::ControlModifier;
+ if (s & qt_alt_mask)
+ ret |= Qt::AltModifier;
+ if (s & qt_meta_mask)
+ ret |= Qt::MetaModifier;
+
+ return ret;
+}
+
+static uint32_t translateKey(uint32_t sym, char *string, size_t size)
+{
+ Q_UNUSED(size);
+ string[0] = '\0';
+
+ switch (sym) {
+ case XK_Escape: return Qt::Key_Escape;
+ case XK_Tab: return Qt::Key_Tab;
+ case XK_ISO_Left_Tab: return Qt::Key_Backtab;
+ case XK_BackSpace: return Qt::Key_Backspace;
+ case XK_Return: return Qt::Key_Return;
+ case XK_Insert: return Qt::Key_Insert;
+ case XK_Delete: return Qt::Key_Delete;
+ case XK_Clear: return Qt::Key_Delete;
+ case XK_Pause: return Qt::Key_Pause;
+ case XK_Print: return Qt::Key_Print;
+
+ case XK_Home: return Qt::Key_Home;
+ case XK_End: return Qt::Key_End;
+ case XK_Left: return Qt::Key_Left;
+ case XK_Up: return Qt::Key_Up;
+ case XK_Right: return Qt::Key_Right;
+ case XK_Down: return Qt::Key_Down;
+ case XK_Prior: return Qt::Key_PageUp;
+ case XK_Next: return Qt::Key_PageDown;
+
+ case XK_Shift_L: return Qt::Key_Shift;
+ case XK_Shift_R: return Qt::Key_Shift;
+ case XK_Shift_Lock: return Qt::Key_Shift;
+ case XK_Control_L: return Qt::Key_Control;
+ case XK_Control_R: return Qt::Key_Control;
+ case XK_Meta_L: return Qt::Key_Meta;
+ case XK_Meta_R: return Qt::Key_Meta;
+ case XK_Alt_L: return Qt::Key_Alt;
+ case XK_Alt_R: return Qt::Key_Alt;
+ case XK_Caps_Lock: return Qt::Key_CapsLock;
+ case XK_Num_Lock: return Qt::Key_NumLock;
+ case XK_Scroll_Lock: return Qt::Key_ScrollLock;
+ case XK_Super_L: return Qt::Key_Super_L;
+ case XK_Super_R: return Qt::Key_Super_R;
+ case XK_Menu: return Qt::Key_Menu;
+
+ default:
+ string[0] = sym;
+ string[1] = '\0';
+ return toupper(sym);
+ }
+}
+#endif
+
+void QWaylandInputDevice::inputHandleKey(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t key, uint32_t state)
+{
+#ifndef QT_NO_WAYLAND_XKB
+ Q_UNUSED(input_device);
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window = inputDevice->mKeyboardFocus;
+ uint32_t code, sym, level;
+ Qt::KeyboardModifiers modifiers;
+ QEvent::Type type;
+ char s[2];
+
+ code = key + inputDevice->mXkb->min_key_code;
+
+ level = 0;
+ if (inputDevice->mModifiers & Qt::ShiftModifier &&
+ XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1)
+ level = 1;
+
+ sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0);
+
+ modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]);
+
+ if (state) {
+ inputDevice->mModifiers |= modifiers;
+ type = QEvent::KeyPress;
+ } else {
+ inputDevice->mModifiers &= ~modifiers;
+ type = QEvent::KeyRelease;
+ }
+
+ sym = translateKey(sym, s, sizeof s);
+
+ qWarning("keycode %d, sym %d, string %d, modifiers 0x%x",
+ code, sym, s[0], (int) inputDevice->mModifiers);
+
+ if (window) {
+ QWindowSystemInterface::handleKeyEvent(window->widget(),
+ time, type, sym,
+ inputDevice->mModifiers,
+ QString::fromLatin1(s));
+ }
+#endif
+}
+
+void QWaylandInputDevice::inputHandlePointerFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t sx, int32_t sy)
+{
+ Q_UNUSED(input_device);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ Q_UNUSED(sx);
+ Q_UNUSED(sy);
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window;
+
+ if (inputDevice->mPointerFocus) {
+ window = inputDevice->mPointerFocus;
+ QWindowSystemInterface::handleLeaveEvent(window->widget());
+ inputDevice->mPointerFocus = NULL;
+ }
+
+ if (surface) {
+ window = (QWaylandWindow *) wl_surface_get_user_data(surface);
+ QWindowSystemInterface::handleEnterEvent(window->widget());
+ inputDevice->mPointerFocus = window;
+ }
+
+ inputDevice->mTime = time;
+}
+
+void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ struct wl_array *keys)
+{
+#ifndef QT_NO_WAYLAND_XKB
+ Q_UNUSED(input_device);
+ Q_UNUSED(time);
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window;
+ uint32_t *k, *end;
+ uint32_t code;
+
+ end = (uint32_t *) ((char *) keys->data + keys->size);
+ inputDevice->mModifiers = 0;
+ for (k = (uint32_t *) keys->data; k < end; k++) {
+ code = *k + inputDevice->mXkb->min_key_code;
+ inputDevice->mModifiers |=
+ translateModifiers(inputDevice->mXkb->map->modmap[code]);
+ }
+
+ if (surface) {
+ window = (QWaylandWindow *) wl_surface_get_user_data(surface);
+ inputDevice->mKeyboardFocus = window;
+ QWindowSystemInterface::handleWindowActivated(window->widget());
+ } else {
+ inputDevice->mKeyboardFocus = NULL;
+ QWindowSystemInterface::handleWindowActivated(0);
+ }
+#endif
+}
+
+const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
+ QWaylandInputDevice::inputHandleMotion,
+ QWaylandInputDevice::inputHandleButton,
+ QWaylandInputDevice::inputHandleKey,
+ QWaylandInputDevice::inputHandlePointerFocus,
+ QWaylandInputDevice::inputHandleKeyboardFocus,
+};
+
+void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
+{
+ wl_input_device_attach(mInputDevice, mTime, buffer->buffer(), x, y);
+}
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h
new file mode 100644
index 0000000000..3c83252c33
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 QWAYLANDINPUTDEVICE_H
+#define QWAYLANDINPUTDEVICE_H
+
+#include "qwaylandwindow.h"
+
+#include <QSocketNotifier>
+#include <QObject>
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+
+#include <wayland-client.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandWindow;
+
+class QWaylandInputDevice {
+public:
+ QWaylandInputDevice(struct wl_display *display, uint32_t id);
+ void attach(QWaylandBuffer *buffer, int x, int y);
+ void handleWindowDestroyed(QWaylandWindow *window);
+
+private:
+ struct wl_display *mDisplay;
+ struct wl_input_device *mInputDevice;
+ QWaylandWindow *mPointerFocus;
+ QWaylandWindow *mKeyboardFocus;
+ static const struct wl_input_device_listener inputDeviceListener;
+ Qt::MouseButtons mButtons;
+ QPoint mSurfacePos;
+ QPoint mGlobalPos;
+ struct xkb_desc *mXkb;
+ Qt::KeyboardModifiers mModifiers;
+ uint32_t mTime;
+
+ static void inputHandleMotion(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ int32_t x, int32_t y,
+ int32_t sx, int32_t sy);
+ static void inputHandleButton(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t button, uint32_t state);
+ static void inputHandleKey(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t key, uint32_t state);
+ static void inputHandlePointerFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t sx, int32_t sy);
+ static void inputHandleKeyboardFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ struct wl_array *keys);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
new file mode 100644
index 0000000000..3f3ee5e571
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -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 config.tests 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 "qwaylandintegration.h"
+
+#include "qwaylanddisplay.h"
+#include "qwaylandshmsurface.h"
+#include "qwaylandshmwindow.h"
+
+#include "qgenericunixfontdatabase.h"
+
+#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QPlatformCursor>
+#include <QtGui/QPlatformWindowFormat>
+
+#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)
+ : mFontDb(new QGenericUnixFontDatabase())
+ , mDisplay(new QWaylandDisplay())
+ , mUseOpenGL(useOpenGL)
+{
+}
+
+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();
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+#ifdef QT_WAYLAND_GL_SUPPORT
+ if (mUseOpenGL)
+ return new QGLPixmapData(type);
+#endif
+ return new QRasterPixmapData(type);
+}
+
+QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+#ifdef QT_WAYLAND_GL_SUPPORT
+ bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
+ if (useOpenGL)
+ return mDisplay->eglIntegration()->createEglWindow(widget);
+#endif
+ return new QWaylandShmWindow(widget);
+}
+
+QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) 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);
+}
+
+QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
+bool QWaylandIntegration::hasOpenGL() const
+{
+#ifdef QT_WAYLAND_GL_SUPPORT
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
new file mode 100644
index 0000000000..fc9b8d6a6e
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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 QPLATFORMINTEGRATION_WAYLAND_H
+#define QPLATFORMINTEGRATION_WAYLAND_H
+
+#include <QtGui/QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandBuffer;
+class QWaylandDisplay;
+
+class QWaylandIntegration : public QPlatformIntegration
+{
+public:
+ QWaylandIntegration(bool useOpenGL = false);
+
+ 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;
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+private:
+ bool hasOpenGL() const;
+
+ QPlatformFontDatabase *mFontDb;
+ QWaylandDisplay *mDisplay;
+ bool mUseOpenGL;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp
new file mode 100644
index 0000000000..4f50cb61e6
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** 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 "qwaylandscreen.h"
+
+#include "qwaylanddisplay.h"
+#include "qwaylandcursor.h"
+
+QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output, QRect geometry)
+ : QPlatformScreen()
+ , mWaylandDisplay(waylandDisplay)
+ , mOutput(output)
+ , mGeometry(geometry)
+ , mDepth(32)
+ , mFormat(QImage::Format_ARGB32_Premultiplied)
+ , mWaylandCursor(new QWaylandCursor(this))
+{
+ moveToThread(waylandDisplay->thread());
+}
+
+QWaylandScreen::~QWaylandScreen()
+{
+ delete mWaylandCursor;
+}
+
+QWaylandDisplay * QWaylandScreen::display() const
+{
+ return mWaylandDisplay;
+}
+
+QRect QWaylandScreen::geometry() const
+{
+ return mGeometry;
+}
+
+int QWaylandScreen::depth() const
+{
+ return mDepth;
+}
+
+QImage::Format QWaylandScreen::format() const
+{
+ return mFormat;
+}
+
+QWaylandScreen * QWaylandScreen::waylandScreenFromWidget(QWidget *widget)
+{
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWidget(widget);
+ return static_cast<QWaylandScreen *>(platformScreen);
+}
+
+wl_visual * QWaylandScreen::visual() const
+{
+ struct wl_visual *visual;
+
+ switch (format()) {
+ case QImage::Format_ARGB32:
+ visual = mWaylandDisplay->argbVisual();
+ break;
+ case QImage::Format_ARGB32_Premultiplied:
+ visual = mWaylandDisplay->argbPremultipliedVisual();
+ break;
+ default:
+ qDebug("unsupported buffer format %d requested\n", format());
+ visual = mWaylandDisplay->argbVisual();
+ break;
+ }
+ return visual;
+}
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h
new file mode 100644
index 0000000000..7784646da9
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandscreen.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 QWAYLANDSCREEN_H
+#define QWAYLANDSCREEN_H
+
+#include <QtGui/QPlatformScreen>
+
+class QWaylandDisplay;
+class QWaylandCursor;
+struct wl_visual;
+
+class QWaylandScreen : public QPlatformScreen
+{
+public:
+ QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output, QRect geometry);
+ ~QWaylandScreen();
+
+ QWaylandDisplay *display() const;
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+
+ wl_visual *visual() const;
+
+ static QWaylandScreen *waylandScreenFromWidget(QWidget *widget);
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ struct wl_output *mOutput;
+ QRect mGeometry;
+ int mDepth;
+ QImage::Format mFormat;
+ QSize mPhysicalSize;
+ QWaylandCursor *mWaylandCursor;
+};
+
+#endif // QWAYLANDSCREEN_H
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
new file mode 100644
index 0000000000..34f4436f25
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmsurface.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$
+** 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 "qwaylandshmsurface.h"
+
+#include <QtCore/qdebug.h>
+#include <QtGui/private/qapplication_p.h>
+
+#include "qwaylanddisplay.h"
+#include "qwaylandshmwindow.h"
+#include "qwaylandscreen.h"
+
+#include <wayland-client.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ const QSize &size, QImage::Format format)
+{
+ int stride = size.width() * 4;
+ int alloc = stride * size.height();
+ char filename[] = "/tmp/wayland-shm-XXXXXX";
+ int fd = mkstemp(filename);
+ if (fd < 0)
+ qWarning("open %s failed: %s", filename, strerror(errno));
+ if (ftruncate(fd, alloc) < 0) {
+ qWarning("ftruncate failed: %s", strerror(errno));
+ close(fd);
+ return;
+ }
+ uchar *data = (uchar *)
+ mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ unlink(filename);
+
+ if (data == (uchar *) MAP_FAILED) {
+ qWarning("mmap /dev/zero failed: %s", strerror(errno));
+ close(fd);
+ return;
+ }
+
+ mImage = QImage(data, size.width(), size.height(), stride, format);
+ mBuffer = display->createShmBuffer(fd, size.width(), size.height(),
+ stride, display->argbVisual());
+ close(fd);
+}
+
+QWaylandShmBuffer::~QWaylandShmBuffer(void)
+{
+ munmap((void *) mImage.constBits(), mImage.byteCount());
+ wl_buffer_destroy(mBuffer);
+}
+
+QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window)
+ : QWindowSurface(window)
+ , mBuffer(0)
+ , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
+{
+}
+
+QWaylandShmWindowSurface::~QWaylandShmWindowSurface()
+{
+}
+
+QPaintDevice *QWaylandShmWindowSurface::paintDevice()
+{
+ return mBuffer->image();
+}
+
+void QWaylandShmWindowSurface::beginPaint(const QRegion &)
+{
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+ Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+ waylandWindow->waitForFrameSync();
+}
+
+void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(offset);
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+ Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+ waylandWindow->damage(region);
+}
+
+void QWaylandShmWindowSurface::resize(const QSize &size)
+{
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+ Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+
+ QWindowSurface::resize(size);
+ QImage::Format format = QPlatformScreen::platformScreenForWidget(window())->format();
+
+ if (mBuffer != NULL && mBuffer->size() == size)
+ return;
+
+ if (mBuffer != NULL)
+ delete mBuffer;
+
+ mBuffer = new QWaylandShmBuffer(mDisplay, size, format);
+
+ waylandWindow->attach(mBuffer);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.h b/src/plugins/platforms/wayland/qwaylandshmsurface.h
new file mode 100644
index 0000000000..b29ceaf1b8
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmsurface.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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 QWINDOWSURFACE_WAYLAND_H
+#define QWINDOWSURFACE_WAYLAND_H
+
+#include "qwaylandbuffer.h"
+#include <QtGui/private/qwindowsurface_p.h>
+
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandDisplay;
+
+class QWaylandShmBuffer : public QWaylandBuffer {
+public:
+ QWaylandShmBuffer(QWaylandDisplay *display,
+ const QSize &size, QImage::Format format);
+ ~QWaylandShmBuffer();
+ QSize size() const { return mImage.size(); }
+ QImage *image() { return &mImage; }
+private:
+ QImage mImage;
+};
+
+class QWaylandShmWindowSurface : public QWindowSurface
+{
+public:
+ QWaylandShmWindowSurface(QWidget *window);
+ ~QWaylandShmWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size);
+ void beginPaint(const QRegion &);
+
+private:
+ QWaylandShmBuffer *mBuffer;
+ QWaylandDisplay *mDisplay;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
new file mode 100644
index 0000000000..c083e58305
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
@@ -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 config.tests 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 "qwaylandshmwindow.h"
+
+#include "qwaylandbuffer.h"
+
+#include <QtCore/QVector>
+
+#include <QtCore/QDebug>
+
+QWaylandShmWindow::QWaylandShmWindow(QWidget *widget)
+ : QWaylandWindow(widget)
+{
+ newSurfaceCreated();
+}
+
+QWaylandShmWindow::~QWaylandShmWindow()
+{
+
+}
+
+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
new file mode 100644
index 0000000000..5dc6351c46
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** 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 config.tests 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 QWAYLANDSHMWINDOW_H
+#define QWAYLANDSHMWINDOW_H
+
+#include "qwaylandwindow.h"
+#include <QtGui/QRegion>
+
+class QWaylandShmWindow : public QWaylandWindow
+{
+public:
+ QWaylandShmWindow(QWidget *widget);
+ ~QWaylandShmWindow();
+
+ WindowType windowType() const;
+ QPlatformGLContext *glContext() const;
+};
+
+#endif // QWAYLANDSHMWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
new file mode 100644
index 0000000000..6f522911d7
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -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 config.tests 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 "qwaylandwindow.h"
+
+#include "qwaylandbuffer.h"
+#include "qwaylanddisplay.h"
+#include "qwaylandinputdevice.h"
+#include "qwaylandscreen.h"
+
+#include <QtGui/QWidget>
+#include <QtGui/QWindowSystemInterface>
+
+#include <QDebug>
+
+QWaylandWindow::QWaylandWindow(QWidget *window)
+ : QPlatformWindow(window)
+ , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
+ , mBuffer(0)
+ , mWaitingForFrameSync(false)
+{
+ static WId id = 1;
+ mWindowId = id++;
+
+ mSurface = mDisplay->createSurface(this);
+}
+
+QWaylandWindow::~QWaylandWindow()
+{
+ if (mSurface)
+ wl_surface_destroy(mSurface);
+
+ QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices();
+ for (int i = 0; i < inputDevices.size(); ++i)
+ inputDevices.at(i)->handleWindowDestroyed(this);
+}
+
+WId QWaylandWindow::winId() const
+{
+ return mWindowId;
+}
+
+void QWaylandWindow::setParent(const QPlatformWindow *parent)
+{
+ Q_UNUSED(parent);
+ qWarning("Sub window is not supported");
+}
+
+void QWaylandWindow::setVisible(bool visible)
+{
+ if (!mSurface && visible) {
+ mSurface = mDisplay->createSurface(this);
+ newSurfaceCreated();
+ }
+
+ if (visible) {
+ wl_surface_map_toplevel(mSurface);
+ } else {
+ wl_surface_destroy(mSurface);
+ mSurface = NULL;
+ }
+}
+
+void QWaylandWindow::configure(uint32_t time, uint32_t edges,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ Q_UNUSED(time);
+ Q_UNUSED(edges);
+ QRect geometry = QRect(x, y, width, height);
+
+ setGeometry(geometry);
+
+ QWindowSystemInterface::handleGeometryChange(widget(), geometry);
+}
+
+void QWaylandWindow::attach(QWaylandBuffer *buffer)
+{
+ mBuffer = buffer;
+ if (mSurface) {
+ wl_surface_attach(mSurface, buffer->buffer(),0,0);
+ }
+}
+
+
+void QWaylandWindow::damage(const QRegion &region)
+{
+ //We have to do sync stuff before calling damage, or we might
+ //get a frame callback before we get the timestamp
+ mDisplay->frameCallback(QWaylandWindow::frameCallback, mSurface, this);
+ mWaitingForFrameSync = true;
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i < rects.size(); i++) {
+ const QRect rect = rects.at(i);
+ wl_surface_damage(mSurface,
+ rect.x(), rect.y(), rect.width(), rect.height());
+ }
+}
+
+void QWaylandWindow::newSurfaceCreated()
+{
+ if (mBuffer) {
+ wl_surface_attach(mSurface,mBuffer->buffer(),0,0);
+ }
+}
+
+void QWaylandWindow::frameCallback(struct wl_surface *surface, void *data, uint32_t time)
+{
+ Q_UNUSED(time);
+ QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
+ self->mWaitingForFrameSync = false;
+}
+
+void QWaylandWindow::waitForFrameSync()
+{
+ mDisplay->flushRequests();
+ while (mWaitingForFrameSync)
+ mDisplay->blockingReadEvents();
+}
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h
new file mode 100644
index 0000000000..1e605088ad
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandwindow.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 config.tests 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 QWAYLANDWINDOW_H
+#define QWAYLANDWINDOW_H
+
+#include <QtGui/QPlatformWindow>
+#include <QtCore/QWaitCondition>
+
+#include "qwaylanddisplay.h"
+
+class QWaylandDisplay;
+class QWaylandBuffer;
+struct wl_egl_window;
+
+class QWaylandWindow : public QPlatformWindow
+{
+public:
+ enum WindowType {
+ Shm,
+ Egl
+ };
+
+ QWaylandWindow(QWidget *window);
+ ~QWaylandWindow();
+
+ virtual WindowType windowType() const = 0;
+ WId winId() const;
+ void setVisible(bool visible);
+ void setParent(const QPlatformWindow *parent);
+
+ void configure(uint32_t time, uint32_t edges,
+ int32_t x, int32_t y, int32_t width, int32_t height);
+
+ void attach(QWaylandBuffer *buffer);
+ void damage(const QRegion &region);
+
+ void waitForFrameSync();
+protected:
+ struct wl_surface *mSurface;
+ virtual void newSurfaceCreated();
+ QWaylandDisplay *mDisplay;
+ QWaylandBuffer *mBuffer;
+ WId mWindowId;
+ bool mWaitingForFrameSync;
+ QWaitCondition mFrameSyncWait;
+
+private:
+ static void frameCallback(struct wl_surface *surface, void *data, uint32_t time);
+
+
+};
+
+
+#endif // QWAYLANDWINDOW_H
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
new file mode 100644
index 0000000000..59454384c2
--- /dev/null
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -0,0 +1,39 @@
+TARGET = qwayland
+include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+DEFINES += Q_PLATFORM_WAYLAND
+DEFINES += $$QMAKE_DEFINES_WAYLAND
+
+SOURCES = main.cpp \
+ qwaylandintegration.cpp \
+ qwaylandshmsurface.cpp \
+ qwaylandinputdevice.cpp \
+ qwaylandcursor.cpp \
+ qwaylanddisplay.cpp \
+ qwaylandwindow.cpp \
+ qwaylandscreen.cpp \
+ qwaylandshmwindow.cpp
+
+HEADERS = qwaylandintegration.h \
+ qwaylandcursor.h \
+ qwaylanddisplay.h \
+ qwaylandwindow.h \
+ qwaylandscreen.h \
+ qwaylandshmsurface.h \
+ qwaylandbuffer.h \
+ qwaylandshmwindow.h
+
+INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
+LIBS += $$QMAKE_LIBS_WAYLAND
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND
+
+INCLUDEPATH += $$PWD
+
+include ($$PWD/gl_integration/gl_integration.pri)
+
+include (../fontdatabases/genericunix/genericunix.pri)
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
new file mode 100644
index 0000000000..17a86e6d08
--- /dev/null
+++ b/src/plugins/platforms/xcb/README
@@ -0,0 +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
+
diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/main.cpp
new file mode 100644
index 0000000000..89bc66e052
--- /dev/null
+++ b/src/plugins/platforms/xcb/main.cpp
@@ -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$
+** 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 <QtGui/QPlatformIntegrationPlugin>
+#include "qxcbintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXcbIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QXcbIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "xcb";
+ return list;
+}
+
+QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "xcb")
+ return new QXcbIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(xcb, QXcbIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qdri2context.cpp b/src/plugins/platforms/xcb/qdri2context.cpp
new file mode 100644
index 0000000000..dbbfa67d8f
--- /dev/null
+++ b/src/plugins/platforms/xcb/qdri2context.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** 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 "qdri2context.h"
+
+#include "qxcbwindow.h"
+#include "qxcbconnection.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/QWidget>
+
+#include <xcb/dri2.h>
+#include <xcb/xfixes.h>
+
+#define MESA_EGL_NO_X11_HEADERS
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#define GL_GLEXT_PROTOTYPES
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+class QDri2ContextPrivate
+{
+public:
+ QDri2ContextPrivate(QXcbWindow *window)
+ : qXcbWindow(window)
+ , windowFormat(window->widget()->platformWindowFormat())
+ , image(0)
+ {
+ }
+
+ xcb_window_t xcbWindow() { return qXcbWindow->window(); }
+ xcb_connection_t *xcbConnection() { return qXcbWindow->xcb_connection(); }
+
+ QXcbWindow *qXcbWindow;
+ QPlatformWindowFormat windowFormat;
+
+ EGLContext eglContext;
+
+ EGLImageKHR image;
+
+ GLuint fbo;
+ GLuint rbo;
+ GLuint depth;
+
+ QSize size;
+};
+
+QDri2Context::QDri2Context(QXcbWindow *window)
+ : d_ptr(new QDri2ContextPrivate(window))
+{
+ Q_D(QDri2Context);
+
+ static const EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+
+ EGLContext shareContext = EGL_NO_CONTEXT;
+ if (window->widget()->platformWindowFormat().sharedGLContext()) {
+ QDri2Context *context = static_cast<QDri2Context *>(window->widget()->platformWindowFormat().sharedGLContext());
+ shareContext = context->d_func()->eglContext;
+ }
+ d->eglContext = eglCreateContext(EGL_DISPLAY_FROM_XCB(d->qXcbWindow), NULL,
+ shareContext, contextAttribs);
+
+ if (d->eglContext == EGL_NO_CONTEXT) {
+ qDebug() << "No eglContext!" << eglGetError();
+ }
+
+ EGLBoolean makeCurrentSuccess = eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,d->eglContext);
+ if (!makeCurrentSuccess) {
+ qDebug() << "eglMakeCurrent failed!" << eglGetError();
+ }
+
+ xcb_dri2_create_drawable (d->xcbConnection(), d->xcbWindow());
+
+ glGenFramebuffers(1,&d->fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER,d->fbo);
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenRenderbuffers(1, &d->rbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, d->rbo);
+
+ glGenRenderbuffers(1,&d->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, d->depth);
+
+ resize(d->qXcbWindow->widget()->geometry().size());
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, d->rbo);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERER,d->depth);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERER,d->depth);
+
+ //restore the old current context
+ const QPlatformGLContext *currentContext = QPlatformGLContext::currentContext();
+ if (currentContext)
+ const_cast<QPlatformGLContext*>(currentContext)->makeCurrent();
+}
+
+QDri2Context::~QDri2Context()
+{
+ //cleanup
+}
+
+void QDri2Context::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+ Q_D(QDri2Context);
+
+ eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,d->eglContext);
+ glBindFramebuffer(GL_FRAMEBUFFER,d->fbo);
+
+}
+
+void QDri2Context::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ Q_D(QDri2Context);
+ eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+}
+
+void QDri2Context::swapBuffers()
+{
+ Q_D(QDri2Context);
+ xcb_rectangle_t rectangle;
+ rectangle.x = 0;
+ rectangle.y = 0;
+ rectangle.width = d->qXcbWindow->widget()->geometry().width();
+ rectangle.height = d->qXcbWindow->widget()->geometry().height();
+
+ xcb_xfixes_region_t xfixesRegion = xcb_generate_id(d->xcbConnection());
+ xcb_xfixes_create_region(d->xcbConnection(), xfixesRegion,
+ 1, &rectangle);
+
+ xcb_dri2_copy_region_cookie_t cookie = xcb_dri2_copy_region_unchecked(d->xcbConnection(),
+ d->qXcbWindow->window(),
+ xfixesRegion,
+ XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
+ XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT);
+
+ xcb_dri2_copy_region_reply_t *reply = xcb_dri2_copy_region_reply(d->xcbConnection(),cookie,NULL);
+
+ //cleanup
+ delete reply;
+ xcb_xfixes_destroy_region(d->xcbConnection(), xfixesRegion);
+
+}
+
+void * QDri2Context::getProcAddress(const QString &procName)
+{
+ return (void *)eglGetProcAddress(qPrintable(procName));
+}
+
+void QDri2Context::resize(const QSize &size)
+{
+ Q_D(QDri2Context);
+ d->size= size;
+
+ glBindFramebuffer(GL_FRAMEBUFFER,d->fbo);
+
+ xcb_dri2_dri2_buffer_t *backBfr = backBuffer();
+
+ if (d->image) {
+ qDebug() << "destroing image";
+ eglDestroyImageKHR(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),d->image);
+ }
+
+ EGLint imgAttribs[] = {
+ EGL_WIDTH, d->size.width(),
+ EGL_HEIGHT, d->size.height(),
+ EGL_DRM_BUFFER_STRIDE_MESA, backBfr->pitch /4,
+ EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+ EGL_NONE
+ };
+
+ d->image = eglCreateImageKHR(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),
+ EGL_NO_CONTEXT,
+ EGL_DRM_BUFFER_MESA,
+ (EGLClientBuffer) backBfr->name,
+ imgAttribs);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, d->rbo);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
+ d->image);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, d->depth);
+ glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8_OES,d->size.width(), d->size.height());
+
+}
+
+QPlatformWindowFormat QDri2Context::platformWindowFormat() const
+{
+ Q_D(const QDri2Context);
+ return d->windowFormat;
+}
+
+xcb_dri2_dri2_buffer_t * QDri2Context::backBuffer()
+{
+ Q_D(QDri2Context);
+
+ unsigned int backBufferAttachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT;
+ xcb_dri2_get_buffers_cookie_t cookie = xcb_dri2_get_buffers_unchecked (d->xcbConnection(),
+ d->xcbWindow(),
+ 1, 1, &backBufferAttachment);
+
+ xcb_dri2_get_buffers_reply_t *reply = xcb_dri2_get_buffers_reply (d->xcbConnection(), cookie, NULL);
+ if (!reply) {
+ qDebug() << "failed to get buffers reply";
+ return 0;
+ }
+
+ xcb_dri2_dri2_buffer_t *buffers = xcb_dri2_get_buffers_buffers (reply);
+ if (!buffers) {
+ qDebug() << "failed to get buffers";
+ return 0;
+ }
+
+ Q_ASSERT(reply->count == 1);
+
+ delete reply;
+
+ return buffers;
+}
+
+void * QDri2Context::eglContext() const
+{
+ Q_D(const QDri2Context);
+ return d->eglContext;
+}
diff --git a/src/plugins/platforms/xcb/qdri2context.h b/src/plugins/platforms/xcb/qdri2context.h
new file mode 100644
index 0000000000..42dd6bd590
--- /dev/null
+++ b/src/plugins/platforms/xcb/qdri2context.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 QDRI2CONTEXT_H
+#define QDRI2CONTEXT_H
+
+#include <QtGui/QPlatformGLContext>
+
+class QXcbWindow;
+class QDri2ContextPrivate;
+
+struct xcb_dri2_dri2_buffer_t;
+
+class QDri2Context : public QPlatformGLContext
+{
+ Q_DECLARE_PRIVATE(QDri2Context);
+public:
+ QDri2Context(QXcbWindow *window);
+ ~QDri2Context();
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ void resize(const QSize &size);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ void *eglContext() const;
+
+protected:
+ xcb_dri2_dri2_buffer_t *backBuffer();
+ QScopedPointer<QDri2ContextPrivate> d_ptr;
+private:
+ Q_DISABLE_COPY(QDri2Context)
+};
+
+#endif // QDRI2CONTEXT_H
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
new file mode 100644
index 0000000000..190221c5f4
--- /dev/null
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** 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 <QDebug>
+#include <QLibrary>
+#include <QGLFormat>
+
+#include "qxcbwindow.h"
+#include "qxcbscreen.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+
+#include "qglxintegration.h"
+#include "qglxconvenience.h"
+
+#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
+#include <dlfcn.h>
+#endif
+
+QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QPlatformWindowFormat &format)
+ : QPlatformGLContext()
+ , 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();
+
+ 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)
+{
+
+}
+
+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());
+}
+
+void QGLXContext::makeCurrent()
+{
+ Q_XCB_NOOP(m_screen->connection());
+ QPlatformGLContext::makeCurrent();
+ glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context);
+ Q_XCB_NOOP(m_screen->connection());
+}
+
+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()
+{
+ Q_XCB_NOOP(m_screen->connection());
+ glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable);
+ doneCurrent();
+ Q_XCB_NOOP(m_screen->connection());
+}
+
+void* QGLXContext::getProcAddress(const QString& procName)
+{
+ Q_XCB_NOOP(m_screen->connection());
+ typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
+ static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
+ static bool resolved = false;
+
+ if (resolved && !glXGetProcAddressARB)
+ return 0;
+ if (!glXGetProcAddressARB) {
+ QList<QByteArray> glxExt = QByteArray(glXGetClientString(DISPLAY_FROM_XCB(m_screen), GLX_EXTENSIONS)).split(' ');
+ if (glxExt.contains("GLX_ARB_get_proc_address")) {
+#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
+ void *handle = dlopen(NULL, RTLD_LAZY);
+ if (handle) {
+ glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
+ dlclose(handle);
+ }
+ if (!glXGetProcAddressARB)
+#endif
+ {
+ extern const QString qt_gl_library_name();
+// QLibrary lib(qt_gl_library_name());
+ QLibrary lib(QLatin1String("GL"));
+ glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
+ }
+ }
+ resolved = true;
+ }
+ if (!glXGetProcAddressARB)
+ return 0;
+ return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data()));
+}
+
+QPlatformWindowFormat QGLXContext::platformWindowFormat() const
+{
+ return m_windowFormat;
+}
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
new file mode 100644
index 0000000000..99b72a04b5
--- /dev/null
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 QGLXINTEGRATION_H
+#define QGLXINTEGRATION_H
+
+#include "qxcbwindow.h"
+
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformWindowFormat>
+
+#include <QtCore/QMutex>
+
+#include <GL/glx.h>
+
+class QGLXContext : public QPlatformGLContext
+{
+public:
+ QGLXContext(Window window, QXcbScreen *xd, const QPlatformWindowFormat &format);
+ ~QGLXContext();
+
+ virtual void makeCurrent();
+ virtual void doneCurrent();
+ virtual void swapBuffers();
+ virtual void* getProcAddress(const QString& procName);
+
+ GLXContext glxContext() const { return m_context; }
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+private:
+ QXcbScreen *m_screen;
+ Drawable m_drawable;
+ GLXContext m_context;
+ QPlatformWindowFormat m_windowFormat;
+
+ QGLXContext (QXcbScreen *screen, Drawable drawable, GLXContext context);
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
new file mode 100644
index 0000000000..7ad12fe8b1
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -0,0 +1,780 @@
+/****************************************************************************
+**
+** 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 "qxcbconnection.h"
+#include "qxcbkeyboard.h"
+#include "qxcbscreen.h"
+#include "qxcbwindow.h"
+
+#include <QtAlgorithms>
+#include <QSocketNotifier>
+#include <QtGui/private/qapplication_p.h>
+#include <QAbstractEventDispatcher>
+
+#include <QtCore/QDebug>
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef XCB_USE_XLIB
+#include <X11/Xlib.h>
+#include <X11/Xlib-xcb.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>
+}
+#define MESA_EGL_NO_X11_HEADERS
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
+QXcbConnection::QXcbConnection(const char *displayName)
+ : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
+#ifdef XCB_USE_DRI2
+ , m_dri2_major(0)
+ , m_dri2_minor(0)
+ , m_dri2_support_probed(false)
+ , m_has_support_for_dri2(false)
+#endif
+{
+ int primaryScreen = 0;
+
+#ifdef XCB_USE_XLIB
+ Display *dpy = XOpenDisplay(m_displayName.constData());
+ primaryScreen = DefaultScreen(dpy);
+ m_connection = XGetXCBConnection(dpy);
+ XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
+ m_xlib_display = dpy;
+#ifdef XCB_USE_EGL
+ EGLDisplay eglDisplay = eglGetDisplay(dpy);
+ m_egl_display = eglDisplay;
+ EGLint major, minor;
+ eglBindAPI(EGL_OPENGL_ES_API);
+ m_has_egl = eglInitialize(eglDisplay,&major,&minor);
+#endif //XCB_USE_EGL
+#else
+ m_connection = xcb_connect(m_displayName.constData(), &primaryScreen);
+
+#endif //XCB_USE_XLIB
+ m_setup = xcb_get_setup(xcb_connection());
+
+ initializeAllAtoms();
+
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
+
+ int screenNumber = 0;
+ while (it.rem) {
+ m_screens << new QXcbScreen(this, it.data, screenNumber++);
+ xcb_screen_next(&it);
+ }
+
+ m_keyboard = new QXcbKeyboard(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()
+{
+ qDeleteAll(m_screens);
+
+#ifdef XCB_USE_XLIB
+ XCloseDisplay((Display *)m_xlib_display);
+#else
+ xcb_disconnect(xcb_connection());
+#endif
+
+ delete m_keyboard;
+}
+
+QXcbWindow *platformWindowFromId(xcb_window_t id)
+{
+ QWidget *widget = QWidget::find(id);
+ if (widget)
+ return static_cast<QXcbWindow *>(widget->platformWindow());
+ return 0;
+}
+
+#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, window, 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); \
+ } \
+} \
+break;
+
+#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
+{ \
+ event_t *e = (event_t *)event; \
+ if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) \
+ m_keyboard->handler(platformWindow->widget(), e); \
+} \
+break;
+
+//#define XCB_EVENT_DEBUG
+
+void printXcbEvent(const char *message, xcb_generic_event_t *event)
+{
+#ifdef XCB_EVENT_DEBUG
+#define PRINT_XCB_EVENT(ev) \
+ case ev: \
+ printf("%s: %d - %s - sequence: %d\n", message, int(ev), #ev, event->sequence); \
+ break;
+
+ switch (event->response_type & ~0x80) {
+ PRINT_XCB_EVENT(XCB_KEY_PRESS);
+ PRINT_XCB_EVENT(XCB_KEY_RELEASE);
+ PRINT_XCB_EVENT(XCB_BUTTON_PRESS);
+ PRINT_XCB_EVENT(XCB_BUTTON_RELEASE);
+ PRINT_XCB_EVENT(XCB_MOTION_NOTIFY);
+ PRINT_XCB_EVENT(XCB_ENTER_NOTIFY);
+ PRINT_XCB_EVENT(XCB_LEAVE_NOTIFY);
+ PRINT_XCB_EVENT(XCB_FOCUS_IN);
+ PRINT_XCB_EVENT(XCB_FOCUS_OUT);
+ PRINT_XCB_EVENT(XCB_KEYMAP_NOTIFY);
+ PRINT_XCB_EVENT(XCB_EXPOSE);
+ PRINT_XCB_EVENT(XCB_GRAPHICS_EXPOSURE);
+ PRINT_XCB_EVENT(XCB_VISIBILITY_NOTIFY);
+ PRINT_XCB_EVENT(XCB_CREATE_NOTIFY);
+ PRINT_XCB_EVENT(XCB_DESTROY_NOTIFY);
+ PRINT_XCB_EVENT(XCB_UNMAP_NOTIFY);
+ PRINT_XCB_EVENT(XCB_MAP_NOTIFY);
+ PRINT_XCB_EVENT(XCB_MAP_REQUEST);
+ PRINT_XCB_EVENT(XCB_REPARENT_NOTIFY);
+ PRINT_XCB_EVENT(XCB_CONFIGURE_NOTIFY);
+ PRINT_XCB_EVENT(XCB_CONFIGURE_REQUEST);
+ PRINT_XCB_EVENT(XCB_GRAVITY_NOTIFY);
+ PRINT_XCB_EVENT(XCB_RESIZE_REQUEST);
+ PRINT_XCB_EVENT(XCB_CIRCULATE_NOTIFY);
+ PRINT_XCB_EVENT(XCB_CIRCULATE_REQUEST);
+ PRINT_XCB_EVENT(XCB_PROPERTY_NOTIFY);
+ PRINT_XCB_EVENT(XCB_SELECTION_CLEAR);
+ PRINT_XCB_EVENT(XCB_SELECTION_REQUEST);
+ PRINT_XCB_EVENT(XCB_SELECTION_NOTIFY);
+ PRINT_XCB_EVENT(XCB_COLORMAP_NOTIFY);
+ PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE);
+ PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY);
+ default:
+ printf("%s: unknown event - response_type: %d - sequence: %d\n", message, int(event->response_type & ~0x80), int(event->sequence));
+ }
+#else
+ Q_UNUSED(message);
+ Q_UNUSED(event);
+#endif
+}
+
+const char *xcb_errors[] =
+{
+ "Success",
+ "BadRequest",
+ "BadValue",
+ "BadWindow",
+ "BadPixmap",
+ "BadAtom",
+ "BadCursor",
+ "BadFont",
+ "BadMatch",
+ "BadDrawable",
+ "BadAccess",
+ "BadAlloc",
+ "BadColor",
+ "BadGC",
+ "BadIDChoice",
+ "BadName",
+ "BadLength",
+ "BadImplementation",
+ "Unknown"
+};
+
+const char *xcb_protocol_request_codes[] =
+{
+ "Null",
+ "CreateWindow",
+ "ChangeWindowAttributes",
+ "GetWindowAttributes",
+ "DestroyWindow",
+ "DestroySubwindows",
+ "ChangeSaveSet",
+ "ReparentWindow",
+ "MapWindow",
+ "MapSubwindows",
+ "UnmapWindow",
+ "UnmapSubwindows",
+ "ConfigureWindow",
+ "CirculateWindow",
+ "GetGeometry",
+ "QueryTree",
+ "InternAtom",
+ "GetAtomName",
+ "ChangeProperty",
+ "DeleteProperty",
+ "GetProperty",
+ "ListProperties",
+ "SetSelectionOwner",
+ "GetSelectionOwner",
+ "ConvertSelection",
+ "SendEvent",
+ "GrabPointer",
+ "UngrabPointer",
+ "GrabButton",
+ "UngrabButton",
+ "ChangeActivePointerGrab",
+ "GrabKeyboard",
+ "UngrabKeyboard",
+ "GrabKey",
+ "UngrabKey",
+ "AllowEvents",
+ "GrabServer",
+ "UngrabServer",
+ "QueryPointer",
+ "GetMotionEvents",
+ "TranslateCoords",
+ "WarpPointer",
+ "SetInputFocus",
+ "GetInputFocus",
+ "QueryKeymap",
+ "OpenFont",
+ "CloseFont",
+ "QueryFont",
+ "QueryTextExtents",
+ "ListFonts",
+ "ListFontsWithInfo",
+ "SetFontPath",
+ "GetFontPath",
+ "CreatePixmap",
+ "FreePixmap",
+ "CreateGC",
+ "ChangeGC",
+ "CopyGC",
+ "SetDashes",
+ "SetClipRectangles",
+ "FreeGC",
+ "ClearArea",
+ "CopyArea",
+ "CopyPlane",
+ "PolyPoint",
+ "PolyLine",
+ "PolySegment",
+ "PolyRectangle",
+ "PolyArc",
+ "FillPoly",
+ "PolyFillRectangle",
+ "PolyFillArc",
+ "PutImage",
+ "GetImage",
+ "PolyText8",
+ "PolyText16",
+ "ImageText8",
+ "ImageText16",
+ "CreateColormap",
+ "FreeColormap",
+ "CopyColormapAndFree",
+ "InstallColormap",
+ "UninstallColormap",
+ "ListInstalledColormaps",
+ "AllocColor",
+ "AllocNamedColor",
+ "AllocColorCells",
+ "AllocColorPlanes",
+ "FreeColors",
+ "StoreColors",
+ "StoreNamedColor",
+ "QueryColors",
+ "LookupColor",
+ "CreateCursor",
+ "CreateGlyphCursor",
+ "FreeCursor",
+ "RecolorCursor",
+ "QueryBestSize",
+ "QueryExtension",
+ "ListExtensions",
+ "ChangeKeyboardMapping",
+ "GetKeyboardMapping",
+ "ChangeKeyboardControl",
+ "GetKeyboardControl",
+ "Bell",
+ "ChangePointerControl",
+ "GetPointerControl",
+ "SetScreenSaver",
+ "GetScreenSaver",
+ "ChangeHosts",
+ "ListHosts",
+ "SetAccessControl",
+ "SetCloseDownMode",
+ "KillClient",
+ "RotateProperties",
+ "ForceScreenSaver",
+ "SetPointerMapping",
+ "GetPointerMapping",
+ "SetModifierMapping",
+ "GetModifierMapping",
+ "Unknown"
+};
+
+#ifdef Q_XCB_DEBUG
+void QXcbConnection::log(const char *file, int line, int sequence)
+{
+ CallInfo info;
+ info.sequence = sequence;
+ info.file = file;
+ info.line = line;
+ m_callLog << info;
+}
+#endif
+
+void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
+{
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+ printf("XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d\n",
+ int(error->error_code), xcb_errors[clamped_error_code],
+ int(error->sequence), int(error->resource_id),
+ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+ int(error->minor_code));
+#ifdef Q_XCB_DEBUG
+ int i = 0;
+ for (; i < m_callLog.size(); ++i) {
+ if (m_callLog.at(i).sequence == error->sequence) {
+ printf("Caused by: %s:%d\n", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
+ break;
+ } else if (m_callLog.at(i).sequence > error->sequence) {
+ printf("Caused some time before: %s:%d\n", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
+ if (i > 0)
+ printf("and after: %s:%d\n", qPrintable(m_callLog.at(i-1).file), m_callLog.at(i-1).line);
+ break;
+ }
+ }
+ if (i == m_callLog.size() && !m_callLog.isEmpty())
+ printf("Caused some time after: %s:%d\n", qPrintable(m_callLog.first().file), m_callLog.first().line);
+#endif
+}
+
+void QXcbConnection::processXcbEvents()
+{
+ while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection())) {
+ bool handled = true;
+
+ uint response_type = event->response_type & ~0x80;
+
+ if (!response_type) {
+ handleXcbError((xcb_generic_error_t *)event);
+ continue;
+ }
+
+#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
+
+ 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;
+ }
+ if (handled)
+ printXcbEvent("Handled XCB event", event);
+ else
+ printXcbEvent("Unhandled XCB event", event);
+ }
+
+ xcb_flush(xcb_connection());
+}
+
+static const char * xcb_atomnames = {
+ // window-manager <-> client protocols
+ "WM_PROTOCOLS\0"
+ "WM_DELETE_WINDOW\0"
+ "WM_TAKE_FOCUS\0"
+ "_NET_WM_PING\0"
+ "_NET_WM_CONTEXT_HELP\0"
+ "_NET_WM_SYNC_REQUEST\0"
+ "_NET_WM_SYNC_REQUEST_COUNTER\0"
+
+ // ICCCM window state
+ "WM_STATE\0"
+ "WM_CHANGE_STATE\0"
+
+ // Session management
+ "WM_CLIENT_LEADER\0"
+ "WM_WINDOW_ROLE\0"
+ "SM_CLIENT_ID\0"
+
+ // Clipboard
+ "CLIPBOARD\0"
+ "INCR\0"
+ "TARGETS\0"
+ "MULTIPLE\0"
+ "TIMESTAMP\0"
+ "SAVE_TARGETS\0"
+ "CLIP_TEMPORARY\0"
+ "_QT_SELECTION\0"
+ "_QT_CLIPBOARD_SENTINEL\0"
+ "_QT_SELECTION_SENTINEL\0"
+ "CLIPBOARD_MANAGER\0"
+
+ "RESOURCE_MANAGER\0"
+
+ "_XSETROOT_ID\0"
+
+ "_QT_SCROLL_DONE\0"
+ "_QT_INPUT_ENCODING\0"
+
+ "_MOTIF_WM_HINTS\0"
+
+ "DTWM_IS_RUNNING\0"
+ "ENLIGHTENMENT_DESKTOP\0"
+ "_DT_SAVE_MODE\0"
+ "_SGI_DESKS_MANAGER\0"
+
+ // EWMH (aka NETWM)
+ "_NET_SUPPORTED\0"
+ "_NET_VIRTUAL_ROOTS\0"
+ "_NET_WORKAREA\0"
+
+ "_NET_MOVERESIZE_WINDOW\0"
+ "_NET_WM_MOVERESIZE\0"
+
+ "_NET_WM_NAME\0"
+ "_NET_WM_ICON_NAME\0"
+ "_NET_WM_ICON\0"
+
+ "_NET_WM_PID\0"
+
+ "_NET_WM_WINDOW_OPACITY\0"
+
+ "_NET_WM_STATE\0"
+ "_NET_WM_STATE_ABOVE\0"
+ "_NET_WM_STATE_BELOW\0"
+ "_NET_WM_STATE_FULLSCREEN\0"
+ "_NET_WM_STATE_MAXIMIZED_HORZ\0"
+ "_NET_WM_STATE_MAXIMIZED_VERT\0"
+ "_NET_WM_STATE_MODAL\0"
+ "_NET_WM_STATE_STAYS_ON_TOP\0"
+ "_NET_WM_STATE_DEMANDS_ATTENTION\0"
+
+ "_NET_WM_USER_TIME\0"
+ "_NET_WM_USER_TIME_WINDOW\0"
+ "_NET_WM_FULL_PLACEMENT\0"
+
+ "_NET_WM_WINDOW_TYPE\0"
+ "_NET_WM_WINDOW_TYPE_DESKTOP\0"
+ "_NET_WM_WINDOW_TYPE_DOCK\0"
+ "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
+ "_NET_WM_WINDOW_TYPE_MENU\0"
+ "_NET_WM_WINDOW_TYPE_UTILITY\0"
+ "_NET_WM_WINDOW_TYPE_SPLASH\0"
+ "_NET_WM_WINDOW_TYPE_DIALOG\0"
+ "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
+ "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
+ "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
+ "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
+ "_NET_WM_WINDOW_TYPE_COMBO\0"
+ "_NET_WM_WINDOW_TYPE_DND\0"
+ "_NET_WM_WINDOW_TYPE_NORMAL\0"
+ "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
+
+ "_KDE_NET_WM_FRAME_STRUT\0"
+
+ "_NET_STARTUP_INFO\0"
+ "_NET_STARTUP_INFO_BEGIN\0"
+
+ "_NET_SUPPORTING_WM_CHECK\0"
+
+ "_NET_WM_CM_S0\0"
+
+ "_NET_SYSTEM_TRAY_VISUAL\0"
+
+ "_NET_ACTIVE_WINDOW\0"
+
+ // Property formats
+ "COMPOUND_TEXT\0"
+ "TEXT\0"
+ "UTF8_STRING\0"
+
+ // xdnd
+ "XdndEnter\0"
+ "XdndPosition\0"
+ "XdndStatus\0"
+ "XdndLeave\0"
+ "XdndDrop\0"
+ "XdndFinished\0"
+ "XdndTypeList\0"
+ "XdndActionList\0"
+
+ "XdndSelection\0"
+
+ "XdndAware\0"
+ "XdndProxy\0"
+
+ "XdndActionCopy\0"
+ "XdndActionLink\0"
+ "XdndActionMove\0"
+ "XdndActionPrivate\0"
+
+ // Motif DND
+ "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
+ "_MOTIF_DRAG_INITIATOR_INFO\0"
+ "_MOTIF_DRAG_RECEIVER_INFO\0"
+ "_MOTIF_DRAG_WINDOW\0"
+ "_MOTIF_DRAG_TARGETS\0"
+
+ "XmTRANSFER_SUCCESS\0"
+ "XmTRANSFER_FAILURE\0"
+
+ // Xkb
+ "_XKB_RULES_NAMES\0"
+
+ // XEMBED
+ "_XEMBED\0"
+ "_XEMBED_INFO\0"
+
+ // Wacom old. (before version 0.10)
+ "Wacom Stylus\0"
+ "Wacom Cursor\0"
+ "Wacom Eraser\0"
+
+ // Tablet
+ "STYLUS\0"
+ "ERASER\0"
+};
+
+xcb_atom_t QXcbConnection::atom(QXcbAtom::Atom atom)
+{
+ return m_allAtoms[atom];
+}
+
+void QXcbConnection::initializeAllAtoms() {
+ const char *names[QXcbAtom::NAtoms];
+ const char *ptr = xcb_atomnames;
+
+ int i = 0;
+ while (*ptr) {
+ names[i++] = ptr;
+ while (*ptr)
+ ++ptr;
+ ++ptr;
+ }
+
+ Q_ASSERT(i == QXcbAtom::NPredefinedAtoms);
+
+ QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
+ settings_atom_name += m_displayName;
+ names[i++] = settings_atom_name;
+
+ xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms];
+
+ Q_ASSERT(i == QXcbAtom::NAtoms);
+ 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;
+}
+
+void QXcbConnection::sync()
+{
+ // from xcb_aux_sync
+ xcb_get_input_focus_cookie_t cookie = Q_XCB_CALL(xcb_get_input_focus(xcb_connection()));
+ free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
+}
+
+#if defined(XCB_USE_EGL)
+bool QXcbConnection::hasEgl() const
+{
+ return m_has_egl;
+}
+#endif // defined(XCB_USE_EGL)
+
+#ifdef XCB_USE_DRI2
+void QXcbConnection::initializeDri2()
+{
+ xcb_dri2_connect_cookie_t connect_cookie = xcb_dri2_connect_unchecked (m_connection,
+ m_screens[0]->root(),
+ XCB_DRI2_DRIVER_TYPE_DRI);
+
+ xcb_dri2_connect_reply_t *connect = xcb_dri2_connect_reply (m_connection,
+ connect_cookie, NULL);
+
+ if (! connect || connect->driver_name_length + connect->device_name_length == 0) {
+ qDebug() << "Failed to connect to dri2";
+ return;
+ }
+
+ m_dri2_device_name = QByteArray(xcb_dri2_connect_device_name (connect),
+ xcb_dri2_connect_device_name_length (connect));
+ delete connect;
+
+ int fd = open(m_dri2_device_name.constData(), O_RDWR);
+ if (fd < 0) {
+ qDebug() << "InitializeDri2: Could'nt open device << dri2DeviceName";
+ m_dri2_device_name = QByteArray();
+ return;
+ }
+
+ drm_magic_t magic;
+ if (drmGetMagic(fd, &magic)) {
+ qDebug() << "Failed to get drmMagic";
+ return;
+ }
+
+ xcb_dri2_authenticate_cookie_t authenticate_cookie = xcb_dri2_authenticate_unchecked(m_connection,
+ m_screens[0]->root(), magic);
+ xcb_dri2_authenticate_reply_t *authenticate = xcb_dri2_authenticate_reply(m_connection,
+ authenticate_cookie, NULL);
+ if (authenticate == NULL || !authenticate->authenticated) {
+ fprintf(stderr, "DRI2: failed to authenticate\n");
+ free(authenticate);
+ return;
+ }
+
+ delete authenticate;
+
+ EGLDisplay display = eglGetDRMDisplayMESA(fd);
+ if (!display) {
+ fprintf(stderr, "failed to create display\n");
+ return;
+ }
+
+ m_egl_display = display;
+ EGLint major,minor;
+ if (!eglInitialize(display, &major, &minor)) {
+ fprintf(stderr, "failed to initialize display\n");
+ return;
+ }
+}
+
+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) {
+ delete error;
+ delete dri2_query;
+ return false;
+ }
+
+ QXcbConnection *that = const_cast<QXcbConnection *>(this);
+ that->m_dri2_major = dri2_query->major_version;
+ that->m_dri2_minor = dri2_query->minor_version;
+
+ that->m_has_support_for_dri2 = true;
+ that->m_dri2_support_probed = true;
+ }
+ return m_has_support_for_dri2;
+}
+#endif //XCB_USE_DRI2
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
new file mode 100644
index 0000000000..6b5f81047d
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -0,0 +1,331 @@
+/****************************************************************************
+**
+** 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 QXCBCONNECTION_H
+#define QXCBCONNECTION_H
+
+#include <xcb/xcb.h>
+
+#include <QList>
+#include <QObject>
+#include <QVector>
+
+#define Q_XCB_DEBUG
+
+class QXcbScreen;
+
+namespace QXcbAtom {
+ enum Atom {
+ // window-manager <-> client protocols
+ WM_PROTOCOLS,
+ WM_DELETE_WINDOW,
+ WM_TAKE_FOCUS,
+ _NET_WM_PING,
+ _NET_WM_CONTEXT_HELP,
+ _NET_WM_SYNC_REQUEST,
+ _NET_WM_SYNC_REQUEST_COUNTER,
+
+ // ICCCM window state
+ WM_STATE,
+ WM_CHANGE_STATE,
+
+ // Session management
+ WM_CLIENT_LEADER,
+ WM_WINDOW_ROLE,
+ SM_CLIENT_ID,
+
+ // Clipboard
+ CLIPBOARD,
+ INCR,
+ TARGETS,
+ MULTIPLE,
+ TIMESTAMP,
+ SAVE_TARGETS,
+ CLIP_TEMPORARY,
+ _QT_SELECTION,
+ _QT_CLIPBOARD_SENTINEL,
+ _QT_SELECTION_SENTINEL,
+ CLIPBOARD_MANAGER,
+
+ RESOURCE_MANAGER,
+
+ _XSETROOT_ID,
+
+ _QT_SCROLL_DONE,
+ _QT_INPUT_ENCODING,
+
+ _MOTIF_WM_HINTS,
+
+ DTWM_IS_RUNNING,
+ ENLIGHTENMENT_DESKTOP,
+ _DT_SAVE_MODE,
+ _SGI_DESKS_MANAGER,
+
+ // EWMH (aka NETWM)
+ _NET_SUPPORTED,
+ _NET_VIRTUAL_ROOTS,
+ _NET_WORKAREA,
+
+ _NET_MOVERESIZE_WINDOW,
+ _NET_WM_MOVERESIZE,
+
+ _NET_WM_NAME,
+ _NET_WM_ICON_NAME,
+ _NET_WM_ICON,
+
+ _NET_WM_PID,
+
+ _NET_WM_WINDOW_OPACITY,
+
+ _NET_WM_STATE,
+ _NET_WM_STATE_ABOVE,
+ _NET_WM_STATE_BELOW,
+ _NET_WM_STATE_FULLSCREEN,
+ _NET_WM_STATE_MAXIMIZED_HORZ,
+ _NET_WM_STATE_MAXIMIZED_VERT,
+ _NET_WM_STATE_MODAL,
+ _NET_WM_STATE_STAYS_ON_TOP,
+ _NET_WM_STATE_DEMANDS_ATTENTION,
+
+ _NET_WM_USER_TIME,
+ _NET_WM_USER_TIME_WINDOW,
+ _NET_WM_FULL_PLACEMENT,
+
+ _NET_WM_WINDOW_TYPE,
+ _NET_WM_WINDOW_TYPE_DESKTOP,
+ _NET_WM_WINDOW_TYPE_DOCK,
+ _NET_WM_WINDOW_TYPE_TOOLBAR,
+ _NET_WM_WINDOW_TYPE_MENU,
+ _NET_WM_WINDOW_TYPE_UTILITY,
+ _NET_WM_WINDOW_TYPE_SPLASH,
+ _NET_WM_WINDOW_TYPE_DIALOG,
+ _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
+ _NET_WM_WINDOW_TYPE_POPUP_MENU,
+ _NET_WM_WINDOW_TYPE_TOOLTIP,
+ _NET_WM_WINDOW_TYPE_NOTIFICATION,
+ _NET_WM_WINDOW_TYPE_COMBO,
+ _NET_WM_WINDOW_TYPE_DND,
+ _NET_WM_WINDOW_TYPE_NORMAL,
+ _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
+
+ _KDE_NET_WM_FRAME_STRUT,
+
+ _NET_STARTUP_INFO,
+ _NET_STARTUP_INFO_BEGIN,
+
+ _NET_SUPPORTING_WM_CHECK,
+
+ _NET_WM_CM_S0,
+
+ _NET_SYSTEM_TRAY_VISUAL,
+
+ _NET_ACTIVE_WINDOW,
+
+ // Property formats
+ COMPOUND_TEXT,
+ TEXT,
+ UTF8_STRING,
+
+ // Xdnd
+ XdndEnter,
+ XdndPosition,
+ XdndStatus,
+ XdndLeave,
+ XdndDrop,
+ XdndFinished,
+ XdndTypelist,
+ XdndActionList,
+
+ XdndSelection,
+
+ XdndAware,
+ XdndProxy,
+
+ XdndActionCopy,
+ XdndActionLink,
+ XdndActionMove,
+ XdndActionPrivate,
+
+ // Motif DND
+ _MOTIF_DRAG_AND_DROP_MESSAGE,
+ _MOTIF_DRAG_INITIATOR_INFO,
+ _MOTIF_DRAG_RECEIVER_INFO,
+ _MOTIF_DRAG_WINDOW,
+ _MOTIF_DRAG_TARGETS,
+
+ XmTRANSFER_SUCCESS,
+ XmTRANSFER_FAILURE,
+
+ // Xkb
+ _XKB_RULES_NAMES,
+
+ // XEMBED
+ _XEMBED,
+ _XEMBED_INFO,
+
+ XWacomStylus,
+ XWacomCursor,
+ XWacomEraser,
+
+ XTabletStylus,
+ XTabletEraser,
+
+ NPredefinedAtoms,
+
+ _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
+ NAtoms
+ };
+}
+
+class QXcbKeyboard;
+
+class QXcbConnection : public QObject
+{
+ Q_OBJECT
+public:
+ QXcbConnection(const char *displayName = 0);
+ ~QXcbConnection();
+
+ QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
+
+ QList<QXcbScreen *> screens() const { return m_screens; }
+ int primaryScreen() const { return m_primaryScreen; }
+
+ xcb_atom_t atom(QXcbAtom::Atom atom);
+
+ const char *displayName() const { return m_displayName.constData(); }
+
+ xcb_connection_t *xcb_connection() const { return m_connection; }
+
+ QXcbKeyboard *keyboard() const { return m_keyboard; }
+
+#ifdef XCB_USE_XLIB
+ void *xlib_display() const { return m_xlib_display; }
+#endif
+
+#ifdef XCB_USE_DRI2
+ bool hasSupportForDri2() const;
+ QByteArray dri2DeviceName() const { return m_dri2_device_name; }
+#endif
+#ifdef XCB_USE_EGL
+ bool hasEgl() const;
+#endif
+#if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
+ void *egl_display() const { return m_egl_display; }
+#endif
+
+ void sync();
+ void handleXcbError(xcb_generic_error_t *error);
+
+private slots:
+ void processXcbEvents();
+
+private:
+ void initializeAllAtoms();
+ void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
+#ifdef XCB_USE_DRI2
+ void initializeDri2();
+#endif
+
+ xcb_connection_t *m_connection;
+ const xcb_setup_t *m_setup;
+
+ QList<QXcbScreen *> m_screens;
+ int m_primaryScreen;
+
+ xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
+
+ QByteArray m_displayName;
+
+ QXcbKeyboard *m_keyboard;
+
+#if defined(XCB_USE_XLIB)
+ void *m_xlib_display;
+#endif
+
+#ifdef XCB_USE_DRI2
+ uint32_t m_dri2_major;
+ uint32_t m_dri2_minor;
+ bool m_dri2_support_probed;
+ bool m_has_support_for_dri2;
+ QByteArray m_dri2_device_name;
+#endif
+#if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
+ void *m_egl_display;
+ bool m_has_egl;
+#endif
+#ifdef Q_XCB_DEBUG
+ struct CallInfo {
+ int sequence;
+ QByteArray file;
+ int line;
+ };
+ QVector<CallInfo> m_callLog;
+ 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
+};
+
+#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+
+#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)
+{
+ connection->log(file, line, cookie.sequence);
+ return cookie;
+}
+#define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
+#define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
+#define Q_XCB_NOOP(c) q_xcb_call_template(xcb_no_operation(c->xcb_connection()), c, __FILE__, __LINE__);
+#else
+#define Q_XCB_CALL(x) x
+#define Q_XCB_CALL2(x, connection) x
+#define Q_XCB_NOOP(c)
+#endif
+
+
+#if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
+#define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
+#endif //endifXCB_USE_DRI2
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
new file mode 100644
index 0000000000..9df5f14114
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** 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 "qxcbintegration.h"
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+#include "qxcbwindow.h"
+#include "qxcbwindowsurface.h"
+#include "qxcbnativeinterface.h"
+
+#include <xcb/xcb.h>
+
+#include <private/qpixmap_raster_p.h>
+
+#include "qgenericunixfontdatabase.h"
+
+#include <stdio.h>
+
+#ifdef XCB_USE_EGL
+#include <EGL/egl.h>
+#endif
+
+QXcbIntegration::QXcbIntegration()
+ : m_connection(new QXcbConnection)
+{
+ foreach (QXcbScreen *screen, m_connection->screens())
+ m_screens << screen;
+
+ m_fontDatabase = new QGenericUnixFontDatabase();
+ m_nativeInterface = new QXcbNativeInterface;
+}
+
+QXcbIntegration::~QXcbIntegration()
+{
+ delete m_connection;
+}
+
+bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return hasOpenGL();
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPixmapData *QXcbIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QPlatformWindow *QXcbIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QXcbWindow(widget);
+}
+
+QWindowSurface *QXcbIntegration::createWindowSurface(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QXcbWindowSurface(widget);
+}
+
+QList<QPlatformScreen *> QXcbIntegration::screens() const
+{
+ return m_screens;
+}
+
+void QXcbIntegration::moveToScreen(QWidget *window, int screen)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(screen);
+}
+
+bool QXcbIntegration::isVirtualDesktop()
+{
+ return false;
+}
+
+QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
+{
+ return m_fontDatabase;
+}
+
+QPixmap QXcbIntegration::grabWindow(WId window, int x, int y, int width, int height) const
+{
+ Q_UNUSED(window);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ Q_UNUSED(width);
+ Q_UNUSED(height);
+ return QPixmap();
+}
+
+
+bool QXcbIntegration::hasOpenGL() 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;
+}
+
+QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
+{
+ return m_nativeInterface;
+}
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
new file mode 100644
index 0000000000..d27fd716ab
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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 QXCBINTEGRATION_H
+#define QXCBINTEGRATION_H
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_NAMESPACE
+
+class QXcbConnection;
+
+class QXcbIntegration : public QPlatformIntegration
+{
+public:
+ QXcbIntegration();
+ ~QXcbIntegration();
+
+ 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;
+
+ 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;
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+ QPlatformNativeInterface *nativeInterface()const;
+
+private:
+ bool hasOpenGL() const;
+ QList<QPlatformScreen *> m_screens;
+ QXcbConnection *m_connection;
+
+ QPlatformFontDatabase *m_fontDatabase;
+ QPlatformNativeInterface *m_nativeInterface;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
new file mode 100644
index 0000000000..f501c00e94
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -0,0 +1,973 @@
+/****************************************************************************
+**
+** 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 "qxcbkeyboard.h"
+
+#include <xcb/xcb_keysyms.h>
+
+#include <X11/keysym.h>
+
+#include <QtGui/QWindowSystemInterface>
+#include <QtCore/QTextCodec>
+
+#include <stdio.h>
+
+#ifndef XK_ISO_Left_Tab
+#define XK_ISO_Left_Tab 0xFE20
+#endif
+
+#ifndef XK_dead_hook
+#define XK_dead_hook 0xFE61
+#endif
+
+#ifndef XK_dead_horn
+#define XK_dead_horn 0xFE62
+#endif
+
+#ifndef XK_Codeinput
+#define XK_Codeinput 0xFF37
+#endif
+
+#ifndef XK_Kanji_Bangou
+#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */
+#endif
+
+// Fix old X libraries
+#ifndef XK_KP_Home
+#define XK_KP_Home 0xFF95
+#endif
+#ifndef XK_KP_Left
+#define XK_KP_Left 0xFF96
+#endif
+#ifndef XK_KP_Up
+#define XK_KP_Up 0xFF97
+#endif
+#ifndef XK_KP_Right
+#define XK_KP_Right 0xFF98
+#endif
+#ifndef XK_KP_Down
+#define XK_KP_Down 0xFF99
+#endif
+#ifndef XK_KP_Prior
+#define XK_KP_Prior 0xFF9A
+#endif
+#ifndef XK_KP_Next
+#define XK_KP_Next 0xFF9B
+#endif
+#ifndef XK_KP_End
+#define XK_KP_End 0xFF9C
+#endif
+#ifndef XK_KP_Insert
+#define XK_KP_Insert 0xFF9E
+#endif
+#ifndef XK_KP_Delete
+#define XK_KP_Delete 0xFF9F
+#endif
+
+// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
+// multimedia keys. They are included here as not every system has them.
+#define XF86XK_MonBrightnessUp 0x1008FF02
+#define XF86XK_MonBrightnessDown 0x1008FF03
+#define XF86XK_KbdLightOnOff 0x1008FF04
+#define XF86XK_KbdBrightnessUp 0x1008FF05
+#define XF86XK_KbdBrightnessDown 0x1008FF06
+#define XF86XK_Standby 0x1008FF10
+#define XF86XK_AudioLowerVolume 0x1008FF11
+#define XF86XK_AudioMute 0x1008FF12
+#define XF86XK_AudioRaiseVolume 0x1008FF13
+#define XF86XK_AudioPlay 0x1008FF14
+#define XF86XK_AudioStop 0x1008FF15
+#define XF86XK_AudioPrev 0x1008FF16
+#define XF86XK_AudioNext 0x1008FF17
+#define XF86XK_HomePage 0x1008FF18
+#define XF86XK_Mail 0x1008FF19
+#define XF86XK_Start 0x1008FF1A
+#define XF86XK_Search 0x1008FF1B
+#define XF86XK_AudioRecord 0x1008FF1C
+#define XF86XK_Calculator 0x1008FF1D
+#define XF86XK_Memo 0x1008FF1E
+#define XF86XK_ToDoList 0x1008FF1F
+#define XF86XK_Calendar 0x1008FF20
+#define XF86XK_PowerDown 0x1008FF21
+#define XF86XK_ContrastAdjust 0x1008FF22
+#define XF86XK_Back 0x1008FF26
+#define XF86XK_Forward 0x1008FF27
+#define XF86XK_Stop 0x1008FF28
+#define XF86XK_Refresh 0x1008FF29
+#define XF86XK_PowerOff 0x1008FF2A
+#define XF86XK_WakeUp 0x1008FF2B
+#define XF86XK_Eject 0x1008FF2C
+#define XF86XK_ScreenSaver 0x1008FF2D
+#define XF86XK_WWW 0x1008FF2E
+#define XF86XK_Sleep 0x1008FF2F
+#define XF86XK_Favorites 0x1008FF30
+#define XF86XK_AudioPause 0x1008FF31
+#define XF86XK_AudioMedia 0x1008FF32
+#define XF86XK_MyComputer 0x1008FF33
+#define XF86XK_LightBulb 0x1008FF35
+#define XF86XK_Shop 0x1008FF36
+#define XF86XK_History 0x1008FF37
+#define XF86XK_OpenURL 0x1008FF38
+#define XF86XK_AddFavorite 0x1008FF39
+#define XF86XK_HotLinks 0x1008FF3A
+#define XF86XK_BrightnessAdjust 0x1008FF3B
+#define XF86XK_Finance 0x1008FF3C
+#define XF86XK_Community 0x1008FF3D
+#define XF86XK_AudioRewind 0x1008FF3E
+#define XF86XK_BackForward 0x1008FF3F
+#define XF86XK_Launch0 0x1008FF40
+#define XF86XK_Launch1 0x1008FF41
+#define XF86XK_Launch2 0x1008FF42
+#define XF86XK_Launch3 0x1008FF43
+#define XF86XK_Launch4 0x1008FF44
+#define XF86XK_Launch5 0x1008FF45
+#define XF86XK_Launch6 0x1008FF46
+#define XF86XK_Launch7 0x1008FF47
+#define XF86XK_Launch8 0x1008FF48
+#define XF86XK_Launch9 0x1008FF49
+#define XF86XK_LaunchA 0x1008FF4A
+#define XF86XK_LaunchB 0x1008FF4B
+#define XF86XK_LaunchC 0x1008FF4C
+#define XF86XK_LaunchD 0x1008FF4D
+#define XF86XK_LaunchE 0x1008FF4E
+#define XF86XK_LaunchF 0x1008FF4F
+#define XF86XK_ApplicationLeft 0x1008FF50
+#define XF86XK_ApplicationRight 0x1008FF51
+#define XF86XK_Book 0x1008FF52
+#define XF86XK_CD 0x1008FF53
+#define XF86XK_Calculater 0x1008FF54
+#define XF86XK_Clear 0x1008FF55
+#define XF86XK_ClearGrab 0x1008FE21
+#define XF86XK_Close 0x1008FF56
+#define XF86XK_Copy 0x1008FF57
+#define XF86XK_Cut 0x1008FF58
+#define XF86XK_Display 0x1008FF59
+#define XF86XK_DOS 0x1008FF5A
+#define XF86XK_Documents 0x1008FF5B
+#define XF86XK_Excel 0x1008FF5C
+#define XF86XK_Explorer 0x1008FF5D
+#define XF86XK_Game 0x1008FF5E
+#define XF86XK_Go 0x1008FF5F
+#define XF86XK_iTouch 0x1008FF60
+#define XF86XK_LogOff 0x1008FF61
+#define XF86XK_Market 0x1008FF62
+#define XF86XK_Meeting 0x1008FF63
+#define XF86XK_MenuKB 0x1008FF65
+#define XF86XK_MenuPB 0x1008FF66
+#define XF86XK_MySites 0x1008FF67
+#define XF86XK_News 0x1008FF69
+#define XF86XK_OfficeHome 0x1008FF6A
+#define XF86XK_Option 0x1008FF6C
+#define XF86XK_Paste 0x1008FF6D
+#define XF86XK_Phone 0x1008FF6E
+#define XF86XK_Reply 0x1008FF72
+#define XF86XK_Reload 0x1008FF73
+#define XF86XK_RotateWindows 0x1008FF74
+#define XF86XK_RotationPB 0x1008FF75
+#define XF86XK_RotationKB 0x1008FF76
+#define XF86XK_Save 0x1008FF77
+#define XF86XK_Send 0x1008FF7B
+#define XF86XK_Spell 0x1008FF7C
+#define XF86XK_SplitScreen 0x1008FF7D
+#define XF86XK_Support 0x1008FF7E
+#define XF86XK_TaskPane 0x1008FF7F
+#define XF86XK_Terminal 0x1008FF80
+#define XF86XK_Tools 0x1008FF81
+#define XF86XK_Travel 0x1008FF82
+#define XF86XK_Video 0x1008FF87
+#define XF86XK_Word 0x1008FF89
+#define XF86XK_Xfer 0x1008FF8A
+#define XF86XK_ZoomIn 0x1008FF8B
+#define XF86XK_ZoomOut 0x1008FF8C
+#define XF86XK_Away 0x1008FF8D
+#define XF86XK_Messenger 0x1008FF8E
+#define XF86XK_WebCam 0x1008FF8F
+#define XF86XK_MailForward 0x1008FF90
+#define XF86XK_Pictures 0x1008FF91
+#define XF86XK_Music 0x1008FF92
+#define XF86XK_Battery 0x1008FF93
+#define XF86XK_Bluetooth 0x1008FF94
+#define XF86XK_WLAN 0x1008FF95
+#define XF86XK_UWB 0x1008FF96
+#define XF86XK_AudioForward 0x1008FF97
+#define XF86XK_AudioRepeat 0x1008FF98
+#define XF86XK_AudioRandomPlay 0x1008FF99
+#define XF86XK_Subtitle 0x1008FF9A
+#define XF86XK_AudioCycleTrack 0x1008FF9B
+#define XF86XK_Time 0x1008FF9F
+#define XF86XK_Select 0x1008FFA0
+#define XF86XK_View 0x1008FFA1
+#define XF86XK_TopMenu 0x1008FFA2
+#define XF86XK_Suspend 0x1008FFA7
+#define XF86XK_Hibernate 0x1008FFA8
+
+
+// end of XF86keysyms.h
+
+// Special keys used by Qtopia, mapped into the X11 private keypad range.
+#define QTOPIAXK_Select 0x11000601
+#define QTOPIAXK_Yes 0x11000602
+#define QTOPIAXK_No 0x11000603
+#define QTOPIAXK_Cancel 0x11000604
+#define QTOPIAXK_Printer 0x11000605
+#define QTOPIAXK_Execute 0x11000606
+#define QTOPIAXK_Sleep 0x11000607
+#define QTOPIAXK_Play 0x11000608
+#define QTOPIAXK_Zoom 0x11000609
+#define QTOPIAXK_Context1 0x1100060A
+#define QTOPIAXK_Context2 0x1100060B
+#define QTOPIAXK_Context3 0x1100060C
+#define QTOPIAXK_Context4 0x1100060D
+#define QTOPIAXK_Call 0x1100060E
+#define QTOPIAXK_Hangup 0x1100060F
+#define QTOPIAXK_Flip 0x11000610
+
+// keyboard mapping table
+static const unsigned int KeyTbl[] = {
+
+ // misc keys
+
+ XK_Escape, Qt::Key_Escape,
+ XK_Tab, Qt::Key_Tab,
+ XK_ISO_Left_Tab, Qt::Key_Backtab,
+ XK_BackSpace, Qt::Key_Backspace,
+ XK_Return, Qt::Key_Return,
+ XK_Insert, Qt::Key_Insert,
+ XK_Delete, Qt::Key_Delete,
+ XK_Clear, Qt::Key_Delete,
+ XK_Pause, Qt::Key_Pause,
+ XK_Print, Qt::Key_Print,
+ 0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq
+ 0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq
+
+ // cursor movement
+
+ XK_Home, Qt::Key_Home,
+ XK_End, Qt::Key_End,
+ XK_Left, Qt::Key_Left,
+ XK_Up, Qt::Key_Up,
+ XK_Right, Qt::Key_Right,
+ XK_Down, Qt::Key_Down,
+ XK_Prior, Qt::Key_PageUp,
+ XK_Next, Qt::Key_PageDown,
+
+ // modifiers
+
+ XK_Shift_L, Qt::Key_Shift,
+ XK_Shift_R, Qt::Key_Shift,
+ XK_Shift_Lock, Qt::Key_Shift,
+ XK_Control_L, Qt::Key_Control,
+ XK_Control_R, Qt::Key_Control,
+ XK_Meta_L, Qt::Key_Meta,
+ XK_Meta_R, Qt::Key_Meta,
+ XK_Alt_L, Qt::Key_Alt,
+ XK_Alt_R, Qt::Key_Alt,
+ XK_Caps_Lock, Qt::Key_CapsLock,
+ XK_Num_Lock, Qt::Key_NumLock,
+ XK_Scroll_Lock, Qt::Key_ScrollLock,
+ XK_Super_L, Qt::Key_Super_L,
+ XK_Super_R, Qt::Key_Super_R,
+ XK_Menu, Qt::Key_Menu,
+ XK_Hyper_L, Qt::Key_Hyper_L,
+ XK_Hyper_R, Qt::Key_Hyper_R,
+ XK_Help, Qt::Key_Help,
+ 0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab
+ 0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11)
+ 0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12)
+
+ // numeric and function keypad keys
+
+ XK_KP_Space, Qt::Key_Space,
+ XK_KP_Tab, Qt::Key_Tab,
+ XK_KP_Enter, Qt::Key_Enter,
+ //XK_KP_F1, Qt::Key_F1,
+ //XK_KP_F2, Qt::Key_F2,
+ //XK_KP_F3, Qt::Key_F3,
+ //XK_KP_F4, Qt::Key_F4,
+ XK_KP_Home, Qt::Key_Home,
+ XK_KP_Left, Qt::Key_Left,
+ XK_KP_Up, Qt::Key_Up,
+ XK_KP_Right, Qt::Key_Right,
+ XK_KP_Down, Qt::Key_Down,
+ XK_KP_Prior, Qt::Key_PageUp,
+ XK_KP_Next, Qt::Key_PageDown,
+ XK_KP_End, Qt::Key_End,
+ XK_KP_Begin, Qt::Key_Clear,
+ XK_KP_Insert, Qt::Key_Insert,
+ XK_KP_Delete, Qt::Key_Delete,
+ XK_KP_Equal, Qt::Key_Equal,
+ XK_KP_Multiply, Qt::Key_Asterisk,
+ XK_KP_Add, Qt::Key_Plus,
+ XK_KP_Separator, Qt::Key_Comma,
+ XK_KP_Subtract, Qt::Key_Minus,
+ XK_KP_Decimal, Qt::Key_Period,
+ XK_KP_Divide, Qt::Key_Slash,
+
+ // International input method support keys
+
+ // International & multi-key character composition
+ XK_ISO_Level3_Shift, Qt::Key_AltGr,
+ XK_Multi_key, Qt::Key_Multi_key,
+ XK_Codeinput, Qt::Key_Codeinput,
+ XK_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_MultipleCandidate, Qt::Key_MultipleCandidate,
+ XK_PreviousCandidate, Qt::Key_PreviousCandidate,
+
+ // Misc Functions
+ XK_Mode_switch, Qt::Key_Mode_switch,
+ XK_script_switch, Qt::Key_Mode_switch,
+
+ // Japanese keyboard support
+ XK_Kanji, Qt::Key_Kanji,
+ XK_Muhenkan, Qt::Key_Muhenkan,
+ //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
+ XK_Henkan_Mode, Qt::Key_Henkan,
+ XK_Henkan, Qt::Key_Henkan,
+ XK_Romaji, Qt::Key_Romaji,
+ XK_Hiragana, Qt::Key_Hiragana,
+ XK_Katakana, Qt::Key_Katakana,
+ XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
+ XK_Zenkaku, Qt::Key_Zenkaku,
+ XK_Hankaku, Qt::Key_Hankaku,
+ XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
+ XK_Touroku, Qt::Key_Touroku,
+ XK_Massyo, Qt::Key_Massyo,
+ XK_Kana_Lock, Qt::Key_Kana_Lock,
+ XK_Kana_Shift, Qt::Key_Kana_Shift,
+ XK_Eisu_Shift, Qt::Key_Eisu_Shift,
+ XK_Eisu_toggle, Qt::Key_Eisu_toggle,
+ //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
+ //XK_Zen_Koho, Qt::Key_Zen_Koho,
+ //XK_Mae_Koho, Qt::Key_Mae_Koho,
+ XK_Kanji_Bangou, Qt::Key_Codeinput,
+ XK_Zen_Koho, Qt::Key_MultipleCandidate,
+ XK_Mae_Koho, Qt::Key_PreviousCandidate,
+
+#ifdef XK_KOREAN
+ // Korean keyboard support
+ XK_Hangul, Qt::Key_Hangul,
+ XK_Hangul_Start, Qt::Key_Hangul_Start,
+ XK_Hangul_End, Qt::Key_Hangul_End,
+ XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
+ XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
+ XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
+ //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
+ XK_Hangul_Codeinput, Qt::Key_Codeinput,
+ XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
+ XK_Hangul_Banja, Qt::Key_Hangul_Banja,
+ XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
+ XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
+ //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
+ //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
+ //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
+ XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
+ XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
+ XK_Hangul_Special, Qt::Key_Hangul_Special,
+ //XK_Hangul_switch, Qt::Key_Hangul_switch,
+ XK_Hangul_switch, Qt::Key_Mode_switch,
+#endif // XK_KOREAN
+
+ // dead keys
+ XK_dead_grave, Qt::Key_Dead_Grave,
+ XK_dead_acute, Qt::Key_Dead_Acute,
+ XK_dead_circumflex, Qt::Key_Dead_Circumflex,
+ XK_dead_tilde, Qt::Key_Dead_Tilde,
+ XK_dead_macron, Qt::Key_Dead_Macron,
+ XK_dead_breve, Qt::Key_Dead_Breve,
+ XK_dead_abovedot, Qt::Key_Dead_Abovedot,
+ XK_dead_diaeresis, Qt::Key_Dead_Diaeresis,
+ XK_dead_abovering, Qt::Key_Dead_Abovering,
+ XK_dead_doubleacute, Qt::Key_Dead_Doubleacute,
+ XK_dead_caron, Qt::Key_Dead_Caron,
+ XK_dead_cedilla, Qt::Key_Dead_Cedilla,
+ XK_dead_ogonek, Qt::Key_Dead_Ogonek,
+ XK_dead_iota, Qt::Key_Dead_Iota,
+ XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
+ XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
+ XK_dead_belowdot, Qt::Key_Dead_Belowdot,
+ XK_dead_hook, Qt::Key_Dead_Hook,
+ XK_dead_horn, Qt::Key_Dead_Horn,
+
+ // Special keys from X.org - This include multimedia keys,
+ // wireless/bluetooth/uwb keys, special launcher keys, etc.
+ XF86XK_Back, Qt::Key_Back,
+ XF86XK_Forward, Qt::Key_Forward,
+ XF86XK_Stop, Qt::Key_Stop,
+ XF86XK_Refresh, Qt::Key_Refresh,
+ XF86XK_Favorites, Qt::Key_Favorites,
+ XF86XK_AudioMedia, Qt::Key_LaunchMedia,
+ XF86XK_OpenURL, Qt::Key_OpenUrl,
+ XF86XK_HomePage, Qt::Key_HomePage,
+ XF86XK_Search, Qt::Key_Search,
+ XF86XK_AudioLowerVolume, Qt::Key_VolumeDown,
+ XF86XK_AudioMute, Qt::Key_VolumeMute,
+ XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp,
+ XF86XK_AudioPlay, Qt::Key_MediaPlay,
+ XF86XK_AudioStop, Qt::Key_MediaStop,
+ XF86XK_AudioPrev, Qt::Key_MediaPrevious,
+ XF86XK_AudioNext, Qt::Key_MediaNext,
+ XF86XK_AudioRecord, Qt::Key_MediaRecord,
+ XF86XK_Mail, Qt::Key_LaunchMail,
+ XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 5: remap properly
+ XF86XK_Calculator, Qt::Key_Launch1,
+ XF86XK_Memo, Qt::Key_Memo,
+ XF86XK_ToDoList, Qt::Key_ToDoList,
+ XF86XK_Calendar, Qt::Key_Calendar,
+ XF86XK_PowerDown, Qt::Key_PowerDown,
+ XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust,
+ XF86XK_Standby, Qt::Key_Standby,
+ XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp,
+ XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown,
+ XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff,
+ XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp,
+ XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown,
+ XF86XK_PowerOff, Qt::Key_PowerOff,
+ XF86XK_WakeUp, Qt::Key_WakeUp,
+ XF86XK_Eject, Qt::Key_Eject,
+ XF86XK_ScreenSaver, Qt::Key_ScreenSaver,
+ XF86XK_WWW, Qt::Key_WWW,
+ XF86XK_Sleep, Qt::Key_Sleep,
+ XF86XK_LightBulb, Qt::Key_LightBulb,
+ XF86XK_Shop, Qt::Key_Shop,
+ XF86XK_History, Qt::Key_History,
+ XF86XK_AddFavorite, Qt::Key_AddFavorite,
+ XF86XK_HotLinks, Qt::Key_HotLinks,
+ XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust,
+ XF86XK_Finance, Qt::Key_Finance,
+ XF86XK_Community, Qt::Key_Community,
+ XF86XK_AudioRewind, Qt::Key_AudioRewind,
+ XF86XK_BackForward, Qt::Key_BackForward,
+ XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft,
+ XF86XK_ApplicationRight, Qt::Key_ApplicationRight,
+ XF86XK_Book, Qt::Key_Book,
+ XF86XK_CD, Qt::Key_CD,
+ XF86XK_Calculater, Qt::Key_Calculator,
+ XF86XK_Clear, Qt::Key_Clear,
+ XF86XK_ClearGrab, Qt::Key_ClearGrab,
+ XF86XK_Close, Qt::Key_Close,
+ XF86XK_Copy, Qt::Key_Copy,
+ XF86XK_Cut, Qt::Key_Cut,
+ XF86XK_Display, Qt::Key_Display,
+ XF86XK_DOS, Qt::Key_DOS,
+ XF86XK_Documents, Qt::Key_Documents,
+ XF86XK_Excel, Qt::Key_Excel,
+ XF86XK_Explorer, Qt::Key_Explorer,
+ XF86XK_Game, Qt::Key_Game,
+ XF86XK_Go, Qt::Key_Go,
+ XF86XK_iTouch, Qt::Key_iTouch,
+ XF86XK_LogOff, Qt::Key_LogOff,
+ XF86XK_Market, Qt::Key_Market,
+ XF86XK_Meeting, Qt::Key_Meeting,
+ XF86XK_MenuKB, Qt::Key_MenuKB,
+ XF86XK_MenuPB, Qt::Key_MenuPB,
+ XF86XK_MySites, Qt::Key_MySites,
+ XF86XK_News, Qt::Key_News,
+ XF86XK_OfficeHome, Qt::Key_OfficeHome,
+ XF86XK_Option, Qt::Key_Option,
+ XF86XK_Paste, Qt::Key_Paste,
+ XF86XK_Phone, Qt::Key_Phone,
+ XF86XK_Reply, Qt::Key_Reply,
+ XF86XK_Reload, Qt::Key_Reload,
+ XF86XK_RotateWindows, Qt::Key_RotateWindows,
+ XF86XK_RotationPB, Qt::Key_RotationPB,
+ XF86XK_RotationKB, Qt::Key_RotationKB,
+ XF86XK_Save, Qt::Key_Save,
+ XF86XK_Send, Qt::Key_Send,
+ XF86XK_Spell, Qt::Key_Spell,
+ XF86XK_SplitScreen, Qt::Key_SplitScreen,
+ XF86XK_Support, Qt::Key_Support,
+ XF86XK_TaskPane, Qt::Key_TaskPane,
+ XF86XK_Terminal, Qt::Key_Terminal,
+ XF86XK_Tools, Qt::Key_Tools,
+ XF86XK_Travel, Qt::Key_Travel,
+ XF86XK_Video, Qt::Key_Video,
+ XF86XK_Word, Qt::Key_Word,
+ XF86XK_Xfer, Qt::Key_Xfer,
+ XF86XK_ZoomIn, Qt::Key_ZoomIn,
+ XF86XK_ZoomOut, Qt::Key_ZoomOut,
+ XF86XK_Away, Qt::Key_Away,
+ XF86XK_Messenger, Qt::Key_Messenger,
+ XF86XK_WebCam, Qt::Key_WebCam,
+ XF86XK_MailForward, Qt::Key_MailForward,
+ XF86XK_Pictures, Qt::Key_Pictures,
+ XF86XK_Music, Qt::Key_Music,
+ XF86XK_Battery, Qt::Key_Battery,
+ XF86XK_Bluetooth, Qt::Key_Bluetooth,
+ XF86XK_WLAN, Qt::Key_WLAN,
+ XF86XK_UWB, Qt::Key_UWB,
+ XF86XK_AudioForward, Qt::Key_AudioForward,
+ XF86XK_AudioRepeat, Qt::Key_AudioRepeat,
+ XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay,
+ XF86XK_Subtitle, Qt::Key_Subtitle,
+ XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack,
+ XF86XK_Time, Qt::Key_Time,
+ XF86XK_Select, Qt::Key_Select,
+ XF86XK_View, Qt::Key_View,
+ XF86XK_TopMenu, Qt::Key_TopMenu,
+ XF86XK_Bluetooth, Qt::Key_Bluetooth,
+ XF86XK_Suspend, Qt::Key_Suspend,
+ XF86XK_Hibernate, Qt::Key_Hibernate,
+ XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly
+ XF86XK_Launch1, Qt::Key_Launch3,
+ XF86XK_Launch2, Qt::Key_Launch4,
+ XF86XK_Launch3, Qt::Key_Launch5,
+ XF86XK_Launch4, Qt::Key_Launch6,
+ XF86XK_Launch5, Qt::Key_Launch7,
+ XF86XK_Launch6, Qt::Key_Launch8,
+ XF86XK_Launch7, Qt::Key_Launch9,
+ XF86XK_Launch8, Qt::Key_LaunchA,
+ XF86XK_Launch9, Qt::Key_LaunchB,
+ XF86XK_LaunchA, Qt::Key_LaunchC,
+ XF86XK_LaunchB, Qt::Key_LaunchD,
+ XF86XK_LaunchC, Qt::Key_LaunchE,
+ XF86XK_LaunchD, Qt::Key_LaunchF,
+ XF86XK_LaunchE, Qt::Key_LaunchG,
+ XF86XK_LaunchF, Qt::Key_LaunchH,
+
+ // Qtopia keys
+ QTOPIAXK_Select, Qt::Key_Select,
+ QTOPIAXK_Yes, Qt::Key_Yes,
+ QTOPIAXK_No, Qt::Key_No,
+ QTOPIAXK_Cancel, Qt::Key_Cancel,
+ QTOPIAXK_Printer, Qt::Key_Printer,
+ QTOPIAXK_Execute, Qt::Key_Execute,
+ QTOPIAXK_Sleep, Qt::Key_Sleep,
+ QTOPIAXK_Play, Qt::Key_Play,
+ QTOPIAXK_Zoom, Qt::Key_Zoom,
+ QTOPIAXK_Context1, Qt::Key_Context1,
+ QTOPIAXK_Context2, Qt::Key_Context2,
+ QTOPIAXK_Context3, Qt::Key_Context3,
+ QTOPIAXK_Context4, Qt::Key_Context4,
+ QTOPIAXK_Call, Qt::Key_Call,
+ QTOPIAXK_Hangup, Qt::Key_Hangup,
+ QTOPIAXK_Flip, Qt::Key_Flip,
+
+ 0, 0
+};
+
+static const unsigned short katakanaKeysymsToUnicode[] = {
+ 0x0000, 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1,
+ 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3,
+ 0x30FC, 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD,
+ 0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD,
+ 0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC,
+ 0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE,
+ 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9,
+ 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C
+};
+
+static const unsigned short cyrillicKeysymsToUnicode[] = {
+ 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f,
+ 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f,
+ 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
+ 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
+ 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a
+};
+
+static const unsigned short greekKeysymsToUnicode[] = {
+ 0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c,
+ 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015,
+ 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc,
+ 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+ 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
+ 0x03c8, 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short technicalKeysymsToUnicode[] = {
+ 0x0000, 0x23B7, 0x250C, 0x2500, 0x2320, 0x2321, 0x2502, 0x23A1,
+ 0x23A3, 0x23A4, 0x23A6, 0x239B, 0x239D, 0x239E, 0x23A0, 0x23A8,
+ 0x23AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222B,
+ 0x2234, 0x221D, 0x221E, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000,
+ 0x223C, 0x2243, 0x0000, 0x0000, 0x0000, 0x21D4, 0x21D2, 0x2261,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221A, 0x0000,
+ 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222A, 0x2227, 0x2228,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193, 0x0000
+};
+
+static const unsigned short specialKeysymsToUnicode[] = {
+ 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x0000, 0x0000,
+ 0x2424, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
+ 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C,
+ 0x2502, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short publishingKeysymsToUnicode[] = {
+ 0x0000, 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009,
+ 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025,
+ 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a,
+ 0x2105, 0x0000, 0x0000, 0x2012, 0x2329, 0x0000, 0x232a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000,
+ 0x0000, 0x2122, 0x2613, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25af,
+ 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033,
+ 0x0000, 0x271d, 0x0000, 0x25ac, 0x25c0, 0x25b6, 0x25cf, 0x25ae,
+ 0x25e6, 0x25ab, 0x25ad, 0x25b3, 0x25bd, 0x2606, 0x2022, 0x25aa,
+ 0x25b2, 0x25bc, 0x261c, 0x261e, 0x2663, 0x2666, 0x2665, 0x0000,
+ 0x2720, 0x2020, 0x2021, 0x2713, 0x2717, 0x266f, 0x266d, 0x2642,
+ 0x2640, 0x260e, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e, 0x0000
+};
+
+static const unsigned short aplKeysymsToUnicode[] = {
+ 0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003e, 0x0000,
+ 0x2228, 0x2227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00af, 0x0000, 0x22a5, 0x2229, 0x230a, 0x0000, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x2218, 0x0000, 0x2395, 0x0000, 0x22a4, 0x25cb,
+ 0x0000, 0x0000, 0x0000, 0x2308, 0x0000, 0x0000, 0x222a, 0x0000,
+ 0x2283, 0x0000, 0x2282, 0x0000, 0x22a2, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x22a3, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short koreanKeysymsToUnicode[] = {
+ 0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
+ 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
+ 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147,
+ 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f,
+ 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157,
+ 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f,
+ 0x3160, 0x3161, 0x3162, 0x3163, 0x11a8, 0x11a9, 0x11aa, 0x11ab,
+ 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3,
+ 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb,
+ 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x316d,
+ 0x3171, 0x3178, 0x317f, 0x3181, 0x3184, 0x3186, 0x318d, 0x318e,
+ 0x11eb, 0x11f0, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9
+};
+
+static QChar keysymToUnicode(unsigned char byte3, unsigned char byte4)
+{
+ switch (byte3) {
+ case 0x04:
+ // katakana
+ if (byte4 > 0xa0 && byte4 < 0xe0)
+ return QChar(katakanaKeysymsToUnicode[byte4 - 0xa0]);
+ else if (byte4 == 0x7e)
+ return QChar(0x203e); // Overline
+ break;
+ case 0x06:
+ // russian, use lookup table
+ if (byte4 > 0xa0)
+ return QChar(cyrillicKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x07:
+ // greek
+ if (byte4 > 0xa0)
+ return QChar(greekKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x08:
+ // technical
+ if (byte4 > 0xa0)
+ return QChar(technicalKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x09:
+ // special
+ if (byte4 >= 0xe0)
+ return QChar(specialKeysymsToUnicode[byte4 - 0xe0]);
+ break;
+ case 0x0a:
+ // publishing
+ if (byte4 > 0xa0)
+ return QChar(publishingKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x0b:
+ // APL
+ if (byte4 > 0xa0)
+ return QChar(aplKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x0e:
+ // Korean
+ if (byte4 > 0xa0)
+ return QChar(koreanKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ default:
+ break;
+ }
+ return QChar(0x0);
+}
+
+Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s)
+{
+ Qt::KeyboardModifiers ret = 0;
+ if (s & XCB_MOD_MASK_SHIFT)
+ ret |= Qt::ShiftModifier;
+ if (s & XCB_MOD_MASK_CONTROL)
+ ret |= Qt::ControlModifier;
+ if (s & m_alt_mask)
+ ret |= Qt::AltModifier;
+ if (s & m_meta_mask)
+ ret |= Qt::MetaModifier;
+ return ret;
+}
+
+int QXcbKeyboard::translateKeySym(uint key) const
+{
+ int code = -1;
+ int i = 0; // any other keys
+ while (KeyTbl[i]) {
+ if (key == KeyTbl[i]) {
+ code = (int)KeyTbl[i+1];
+ break;
+ }
+ i += 2;
+ }
+ if (m_meta_mask) {
+ // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
+ if (m_meta_mask == m_super_mask && (code == Qt::Key_Super_L || code == Qt::Key_Super_R)) {
+ code = Qt::Key_Meta;
+ } else if (m_meta_mask == m_hyper_mask && (code == Qt::Key_Hyper_L || code == Qt::Key_Hyper_R)) {
+ code = Qt::Key_Meta;
+ }
+ }
+ return code;
+}
+
+QString QXcbKeyboard::translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
+ int &code, Qt::KeyboardModifiers &modifiers,
+ QByteArray &chars, int &count)
+{
+ // all keysyms smaller than 0xff00 are actally keys that can be mapped to unicode chars
+
+ QTextCodec *mapper = QTextCodec::codecForLocale();
+ QChar converted;
+
+ if (/*count == 0 &&*/ keysym < 0xff00) {
+ unsigned char byte3 = (unsigned char)(keysym >> 8);
+ int mib = -1;
+ switch(byte3) {
+ case 0: // Latin 1
+ case 1: // Latin 2
+ case 2: //latin 3
+ case 3: // latin4
+ mib = byte3 + 4; break;
+ case 5: // arabic
+ mib = 82; break;
+ case 12: // Hebrew
+ mib = 85; break;
+ case 13: // Thai
+ mib = 2259; break;
+ case 4: // kana
+ case 6: // cyrillic
+ case 7: // greek
+ case 8: // technical, no mapping here at the moment
+ case 9: // Special
+ case 10: // Publishing
+ case 11: // APL
+ case 14: // Korean, no mapping
+ mib = -1; // manual conversion
+ mapper= 0;
+#if !defined(QT_NO_XIM)
+ converted = keysymToUnicode(byte3, keysym & 0xff);
+#endif
+ case 0x20:
+ // currency symbols
+ if (keysym >= 0x20a0 && keysym <= 0x20ac) {
+ mib = -1; // manual conversion
+ mapper = 0;
+ converted = (uint)keysym;
+ }
+ break;
+ default:
+ break;
+ }
+ if (mib != -1) {
+ mapper = QTextCodec::codecForMib(mib);
+ if (chars.isEmpty())
+ chars.resize(1);
+ chars[0] = (unsigned char) (keysym & 0xff); // get only the fourth bit for conversion later
+ count = 1;
+ }
+ } else if (keysym >= 0x1000000 && keysym <= 0x100ffff) {
+ converted = (ushort) (keysym - 0x1000000);
+ mapper = 0;
+ }
+ if (count < (int)chars.size()-1)
+ chars[count] = '\0';
+
+ QString text;
+ if (!mapper && converted.unicode() != 0x0) {
+ text = converted;
+ } else if (!chars.isEmpty()) {
+ // convert chars (8bit) to text (unicode).
+ if (mapper)
+ text = mapper->toUnicode(chars.data(), count, 0);
+ if (text.isEmpty()) {
+ // no mapper, or codec couldn't convert to unicode (this
+ // can happen when running in the C locale or with no LANG
+ // set). try converting from latin-1
+ text = QString::fromLatin1(chars);
+ }
+ }
+
+ modifiers = translateModifiers(xmodifiers);
+
+ // Commentary in X11/keysymdef says that X codes match ASCII, so it
+ // is safe to use the locale functions to process X codes in ISO8859-1.
+ //
+ // This is mainly for compatibility - applications should not use the
+ // Qt keycodes between 128 and 255, but should rather use the
+ // QKeyEvent::text().
+ //
+ if (keysym < 128 || (keysym < 256 && (!mapper || mapper->mibEnum()==4))) {
+ // upper-case key, if known
+ code = isprint((int)keysym) ? toupper((int)keysym) : 0;
+ } else if (keysym >= XK_F1 && keysym <= XK_F35) {
+ // function keys
+ code = Qt::Key_F1 + ((int)keysym - XK_F1);
+ } else if (keysym >= XK_KP_Space && keysym <= XK_KP_9) {
+ if (keysym >= XK_KP_0) {
+ // numeric keypad keys
+ code = Qt::Key_0 + ((int)keysym - XK_KP_0);
+ } else {
+ code = translateKeySym(keysym);
+ }
+ modifiers |= Qt::KeypadModifier;
+ } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f && text.unicode()->unicode() != 0x7f && !(keysym >= XK_dead_grave && keysym <= XK_dead_horn)) {
+ code = text.unicode()->toUpper().unicode();
+ } else {
+ // any other keys
+ code = translateKeySym(keysym);
+
+ if (code == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) {
+ // map shift+tab to shift+backtab, QShortcutMap knows about it
+ // and will handle it.
+ code = Qt::Key_Backtab;
+ text = QString();
+ }
+ }
+
+ return text;
+}
+
+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());
+}
+
+QXcbKeyboard::~QXcbKeyboard()
+{
+ xcb_key_symbols_free(m_key_symbols);
+}
+
+// #define XCB_KEYBOARD_DEBUG
+
+void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time)
+{
+ int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0;
+
+ const int altGrOffset = 4;
+ if (state & 128)
+ col += altGrOffset;
+
+ Q_XCB_NOOP(connection());
+
+#ifdef XCB_KEYBOARD_DEBUG
+ printf("key code: %d, state: %d, syms: ", code, state);
+ for (int i = 0; i <= 5; ++i) {
+ printf("%d ", xcb_key_symbols_get_keysym(m_key_symbols, code, i));
+ }
+ printf("\n");
+#endif
+
+ Q_XCB_NOOP(connection());
+
+ 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);
+ }
+
+ 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));
+}
+
+void QXcbKeyboard::handleKeyPressEvent(QWidget *widget, const xcb_key_press_event_t *event)
+{
+ handleKeyEvent(widget, QEvent::KeyPress, event->detail, event->state, event->time);
+}
+
+void QXcbKeyboard::handleKeyReleaseEvent(QWidget *widget, const xcb_key_release_event_t *event)
+{
+ handleKeyEvent(widget, 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));
+}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
new file mode 100644
index 0000000000..ddade79d51
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.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$
+** 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 QXCBKEYBOARD_H
+#define QXCBKEYBOARD_H
+
+#include "qxcbobject.h"
+
+#include "xcb/xcb_keysyms.h"
+
+#include <QEvent>
+
+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 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);
+
+ int translateKeySym(uint key) const;
+ QString translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
+ int &code, Qt::KeyboardModifiers &modifiers,
+ QByteArray &chars, int &count);
+
+ uint m_alt_mask;
+ uint m_super_mask;
+ uint m_hyper_mask;
+ uint m_meta_mask;
+ uint m_mode_switch_mask;
+ uint m_num_lock_mask;
+
+ xcb_key_symbols_t *m_key_symbols;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
new file mode 100644
index 0000000000..b2ca1beb6e
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** 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 "qxcbnativeinterface.h"
+
+#include "qxcbscreen.h"
+
+#include <QtGui/private/qapplication_p.h>
+#include <QtCore/QMap>
+
+#include <QtCore/QDebug>
+
+#if defined(XCB_USE_EGL)
+#include "../eglconvenience/qeglplatformcontext.h"
+#elif defined (XCB_USE_DRI2)
+#include "qdri2context.h"
+#endif
+
+class QXcbResourceMap : public QMap<QByteArray, QXcbNativeInterface::ResourceType>
+{
+public:
+ QXcbResourceMap()
+ :QMap<QByteArray, QXcbNativeInterface::ResourceType>()
+ {
+ insert("display",QXcbNativeInterface::Display);
+ insert("egldisplay",QXcbNativeInterface::EglDisplay);
+ insert("connection",QXcbNativeInterface::Connection);
+ insert("screen",QXcbNativeInterface::Screen);
+ insert("graphicsdevice",QXcbNativeInterface::GraphicsDevice);
+ insert("eglcontext",QXcbNativeInterface::EglContext);
+ }
+};
+
+Q_GLOBAL_STATIC(QXcbResourceMap, qXcbResourceMap)
+
+void *QXcbNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qXcbResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch(resource) {
+ case Display:
+ result = displayForWidget(widget);
+ break;
+ case EglDisplay:
+ result = eglDisplayForWidget(widget);
+ break;
+ case Connection:
+ result = connectionForWidget(widget);
+ break;
+ case Screen:
+ result = qPlatformScreenForWidget(widget);
+ break;
+ case GraphicsDevice:
+ result = graphicsDeviceForWidget(widget);
+ break;
+ case EglContext:
+ result = eglContextForWidget(widget);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+QXcbScreen *QXcbNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+{
+ QXcbScreen *screen;
+ if (widget) {
+ screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+ }else {
+ screen = static_cast<QXcbScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+ }
+ return screen;
+}
+
+void *QXcbNativeInterface::displayForWidget(QWidget *widget)
+{
+#if defined(XCB_USE_XLIB)
+ QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ return screen->connection()->xlib_display();
+#else
+ Q_UNUSED(widget);
+ return 0;
+#endif
+}
+
+void *QXcbNativeInterface::eglDisplayForWidget(QWidget *widget)
+{
+#if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
+ QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ return screen->connection()->egl_display();
+#else
+ Q_UNUSED(widget)
+ return 0;
+#endif
+}
+
+void *QXcbNativeInterface::connectionForWidget(QWidget *widget)
+{
+ QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ return screen->xcb_connection();
+}
+
+void *QXcbNativeInterface::screenForWidget(QWidget *widget)
+{
+ QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ return screen->screen();
+}
+
+void *QXcbNativeInterface::graphicsDeviceForWidget(QWidget *widget)
+{
+#if defined(XCB_USE_DRI2)
+ QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QByteArray deviceName = screen->connection()->dri2DeviceName();
+ return deviceName.data();
+#else
+ Q_UNUSED(widget);
+ return 0;
+#endif
+
+}
+
+void * QXcbNativeInterface::eglContextForWidget(QWidget *widget)
+{
+ Q_ASSERT(widget);
+ if (!widget->platformWindow()) {
+ qDebug() << "QPlatformWindow does not exist for widget" << widget
+ << "cannot return EGLContext";
+ return 0;
+ }
+ QPlatformGLContext *platformContext = widget->platformWindow()->glContext();
+ if (!platformContext) {
+ qDebug() << "QPlatformWindow" << widget->platformWindow() << "does not have a glContext"
+ << "cannot return EGLContext";
+ return 0;
+ }
+#if defined(XCB_USE_EGL)
+ QEGLPlatformContext *eglPlatformContext = static_cast<QEGLPlatformContext *>(platformContext);
+ return eglPlatformContext->eglContext();
+#elif defined (XCB_USE_DRI2)
+ QDri2Context *dri2Context = static_cast<QDri2Context *>(platformContext);
+ return dri2Context->eglContext();
+#else
+ return 0;
+#endif
+}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
new file mode 100644
index 0000000000..f60905cc3d
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.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$
+** 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 QXCBNATIVEINTERFACE_H
+#define QXCBNATIVEINTERFACE_H
+
+#include <QtGui/QPlatformNativeInterface>
+
+class QWidget;
+class QXcbScreen;
+
+class QXcbNativeInterface : public QPlatformNativeInterface
+{
+public:
+ enum ResourceType {
+ Display,
+ EglDisplay,
+ Connection,
+ Screen,
+ GraphicsDevice,
+ EglContext
+ };
+
+ void *nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget);
+
+ void *displayForWidget(QWidget *widget);
+ void *eglDisplayForWidget(QWidget *widget);
+ void *connectionForWidget(QWidget *widget);
+ void *screenForWidget(QWidget *widget);
+ void *graphicsDeviceForWidget(QWidget *widget);
+ void *eglContextForWidget(QWidget *widget);
+
+private:
+ static QXcbScreen *qPlatformScreenForWidget(QWidget *widget);
+};
+
+#endif // QXCBNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/xcb/qxcbobject.h b/src/plugins/platforms/xcb/qxcbobject.h
new file mode 100644
index 0000000000..69494b0349
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbobject.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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 QXCBOBJECT_H
+#define QXCBOBJECT_H
+
+#include "qxcbconnection.h"
+
+class QXcbObject
+{
+public:
+ QXcbObject(QXcbConnection *connection = 0) : m_connection(connection) {}
+
+ void setConnection(QXcbConnection *connection) { m_connection = connection; }
+ QXcbConnection *connection() const { return m_connection; }
+
+ xcb_atom_t atom(QXcbAtom::Atom atom) const { return m_connection->atom(atom); }
+ xcb_connection_t *xcb_connection() const { return m_connection->xcb_connection(); }
+
+private:
+ QXcbConnection *m_connection;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
new file mode 100644
index 0000000000..1c12ee3059
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** 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 "qxcbscreen.h"
+
+#include <stdio.h>
+
+QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number)
+ : QXcbObject(connection)
+ , m_screen(screen)
+ , m_number(number)
+{
+ printf ("\n");
+ printf ("Information of screen %d:\n", screen->root);
+ printf (" width.........: %d\n", screen->width_in_pixels);
+ printf (" height........: %d\n", screen->height_in_pixels);
+ printf (" depth.........: %d\n", screen->root_depth);
+ printf (" white pixel...: %x\n", screen->white_pixel);
+ printf (" black pixel...: %x\n", screen->black_pixel);
+ printf ("\n");
+
+ const quint32 mask = XCB_CW_EVENT_MASK;
+ const quint32 values[] = {
+ // XCB_CW_EVENT_MASK
+ XCB_EVENT_MASK_ENTER_WINDOW
+ | XCB_EVENT_MASK_LEAVE_WINDOW
+ | XCB_EVENT_MASK_PROPERTY_CHANGE
+ };
+
+ xcb_change_window_attributes(xcb_connection(), screen->root, mask, values);
+
+ xcb_generic_error_t *error;
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(xcb_connection(),
+ xcb_get_property(xcb_connection(), false, screen->root,
+ atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK),
+ XCB_ATOM_WINDOW, 0, 1024), &error);
+
+ if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) {
+ xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply));
+
+ if (windowManager != XCB_WINDOW_NONE) {
+ xcb_get_property_reply_t *windowManagerReply =
+ xcb_get_property_reply(xcb_connection(),
+ xcb_get_property(xcb_connection(), false, windowManager,
+ atom(QXcbAtom::_NET_WM_NAME),
+ atom(QXcbAtom::UTF8_STRING), 0, 1024), &error);
+ if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) {
+ m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply));
+ printf("Running window manager: %s\n", qPrintable(m_windowManagerName));
+ } else if (error) {
+ connection->handleXcbError(error);
+ free(error);
+ }
+
+ free(windowManagerReply);
+ }
+ } else if (error) {
+ connection->handleXcbError(error);
+ free(error);
+ }
+
+ free(reply);
+
+ m_syncRequestSupported = m_windowManagerName != QLatin1String("KWin");
+}
+
+QXcbScreen::~QXcbScreen()
+{
+}
+
+QRect QXcbScreen::geometry() const
+{
+ return QRect(0, 0, m_screen->width_in_pixels, m_screen->height_in_pixels);
+}
+
+int QXcbScreen::depth() const
+{
+ return m_screen->root_depth;
+}
+
+QImage::Format QXcbScreen::format() const
+{
+ return QImage::Format_RGB32;
+}
+
+QSize QXcbScreen::physicalSize() const
+{
+ return QSize(m_screen->width_in_millimeters, m_screen->height_in_millimeters);
+}
+
+int QXcbScreen::screenNumber() const
+{
+ return m_number;
+}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
new file mode 100644
index 0000000000..9547d016b7
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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 QXCBSCREEN_H
+#define QXCBSCREEN_H
+
+#include <QtGui/QPlatformScreen>
+#include <QtCore/QString>
+
+#include <xcb/xcb.h>
+
+#include "qxcbobject.h"
+
+class QXcbConnection;
+
+class QXcbScreen : public QXcbObject, public QPlatformScreen
+{
+public:
+ QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number);
+ ~QXcbScreen();
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSize physicalSize() const;
+
+ int screenNumber() const;
+
+ xcb_screen_t *screen() const { return m_screen; }
+ xcb_window_t root() const { return m_screen->root; }
+
+ QString windowManagerName() const { return m_windowManagerName; }
+ bool syncRequestSupported() const { return m_syncRequestSupported; }
+
+private:
+ xcb_screen_t *m_screen;
+ int m_number;
+ QString m_windowManagerName;
+ bool m_syncRequestSupported;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
new file mode 100644
index 0000000000..0456638ab9
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -0,0 +1,683 @@
+/****************************************************************************
+**
+** 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 "qxcbwindow.h"
+
+#include <QtDebug>
+
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+#ifdef XCB_USE_DRI2
+#include "qdri2context.h"
+#endif
+
+#include <xcb/xcb_icccm.h>
+
+#include <private/qapplication_p.h>
+#include <private/qwindowsurface_p.h>
+
+#include <QtGui/QWindowSystemInterface>
+
+#include <stdio.h>
+
+#ifdef XCB_USE_XLIB
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+
+#if defined(XCB_USE_GLX)
+#include "qglxintegration.h"
+#include "qglxconvenience.h"
+#elif defined(XCB_USE_EGL)
+#include "../eglconvenience/qeglplatformcontext.h"
+#include "../eglconvenience/qeglconvenience.h"
+#include "../eglconvenience/qxlibeglintegration.h"
+#endif
+
+// Returns true if we should set WM_TRANSIENT_FOR on \a w
+static inline bool isTransient(const QWidget *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));
+}
+
+QXcbWindow::QXcbWindow(QWidget *tlw)
+ : QPlatformWindow(tlw)
+ , m_context(0)
+{
+ m_screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(tlw));
+
+ setConnection(m_screen->connection());
+
+ const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK;
+ const quint32 values[] = {
+ // XCB_CW_BACK_PIXMAP
+ XCB_NONE,
+ // XCB_CW_EVENT_MASK
+ XCB_EVENT_MASK_EXPOSURE
+ | XCB_EVENT_MASK_STRUCTURE_NOTIFY
+ | XCB_EVENT_MASK_KEY_PRESS
+ | XCB_EVENT_MASK_KEY_RELEASE
+ | 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_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))
+ {
+#if defined(XCB_USE_GLX)
+ XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
+#elif defined(XCB_USE_EGL)
+ EGLDisplay eglDisplay = connection()->egl_display();
+ EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,tlw->platformWindowFormat(),true);
+ VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = id;
+
+ XVisualInfo *visualInfo;
+ int matchingCount = 0;
+ visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
+#endif //XCB_USE_GLX
+ if (visualInfo) {
+ Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+
+ printf("created GL window: %d\n", m_window);
+ } else {
+ qFatal("no window!");
+ }
+ } else
+#endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
+ {
+ m_window = xcb_generate_id(xcb_connection());
+
+ 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(),
+ 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);
+ }
+
+ Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
+
+ xcb_atom_t properties[4];
+ int propertyCount = 0;
+ properties[propertyCount++] = atom(QXcbAtom::WM_DELETE_WINDOW);
+ properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
+ properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
+
+ if (m_screen->syncRequestSupported())
+ properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
+
+ if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint)
+ properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
+
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::WM_PROTOCOLS),
+ XCB_ATOM_ATOM,
+ 32,
+ propertyCount,
+ properties));
+ m_syncValue.hi = 0;
+ m_syncValue.lo = 0;
+
+ if (m_screen->syncRequestSupported()) {
+ m_syncCounter = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));
+
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_NET_WM_SYNC_REQUEST_COUNTER),
+ XCB_ATOM_CARDINAL,
+ 32,
+ 1,
+ &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));
+}
+
+QXcbWindow::~QXcbWindow()
+{
+ delete m_context;
+ if (m_screen->syncRequestSupported())
+ Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
+ Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
+}
+
+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() };
+
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
+}
+
+void QXcbWindow::setVisible(bool visible)
+{
+ xcb_wm_hints_t hints;
+ if (visible) {
+ if (widget()->isMinimized())
+ 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());
+ }
+}
+
+struct QtMWMHints {
+ quint32 flags, functions, decorations;
+ qint32 input_mode;
+ quint32 status;
+};
+
+enum {
+ MWM_HINTS_FUNCTIONS = (1L << 0),
+
+ MWM_FUNC_ALL = (1L << 0),
+ MWM_FUNC_RESIZE = (1L << 1),
+ MWM_FUNC_MOVE = (1L << 2),
+ MWM_FUNC_MINIMIZE = (1L << 3),
+ MWM_FUNC_MAXIMIZE = (1L << 4),
+ MWM_FUNC_CLOSE = (1L << 5),
+
+ MWM_HINTS_DECORATIONS = (1L << 1),
+
+ MWM_DECOR_ALL = (1L << 0),
+ MWM_DECOR_BORDER = (1L << 1),
+ MWM_DECOR_RESIZEH = (1L << 2),
+ MWM_DECOR_TITLE = (1L << 3),
+ MWM_DECOR_MENU = (1L << 4),
+ MWM_DECOR_MINIMIZE = (1L << 5),
+ MWM_DECOR_MAXIMIZE = (1L << 6),
+
+ MWM_HINTS_INPUT_MODE = (1L << 2),
+
+ MWM_INPUT_MODELESS = 0L,
+ MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
+ MWM_INPUT_FULL_APPLICATION_MODAL = 3L
+};
+
+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);
+
+ Q_UNUSED(topLevel);
+ Q_UNUSED(dialog);
+ Q_UNUSED(desktop);
+ Q_UNUSED(tool);
+
+ bool tooltip = (type == Qt::ToolTip);
+
+ QtMWMHints mwmhints;
+ mwmhints.flags = 0L;
+ mwmhints.functions = 0L;
+ mwmhints.decorations = 0;
+ mwmhints.input_mode = 0L;
+ mwmhints.status = 0L;
+
+ if (type != Qt::SplashScreen) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+
+ bool customize = flags & Qt::CustomizeWindowHint;
+ if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
+ mwmhints.decorations |= MWM_DECOR_BORDER;
+ mwmhints.decorations |= MWM_DECOR_RESIZEH;
+
+ if (flags & Qt::WindowTitleHint)
+ mwmhints.decorations |= MWM_DECOR_TITLE;
+
+ if (flags & Qt::WindowSystemMenuHint)
+ mwmhints.decorations |= MWM_DECOR_MENU;
+
+ if (flags & Qt::WindowMinimizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+ mwmhints.functions |= MWM_FUNC_MINIMIZE;
+ }
+
+ if (flags & Qt::WindowMaximizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+ mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+ }
+
+ if (flags & Qt::WindowCloseButtonHint)
+ mwmhints.functions |= MWM_FUNC_CLOSE;
+ }
+ } else {
+ // if type == Qt::SplashScreen
+ mwmhints.decorations = MWM_DECOR_ALL;
+ }
+
+ if (mwmhints.functions != 0) {
+ mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+ mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ } else {
+ mwmhints.functions = MWM_FUNC_ALL;
+ }
+
+ if (!(flags & Qt::FramelessWindowHint)
+ && flags & Qt::CustomizeWindowHint
+ && flags & Qt::WindowTitleHint
+ && !(flags &
+ (Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowCloseButtonHint)))
+ {
+ // a special case - only the titlebar without any button
+ mwmhints.flags = MWM_HINTS_FUNCTIONS;
+ mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ 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)));
+ }
+
+ if (popup || tooltip) {
+ const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
+ const quint32 values[] = { true, true };
+
+ Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
+ }
+
+ return QPlatformWindow::setWindowFlags(flags);
+}
+
+void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
+{
+ // in order of decreasing priority
+ QVector<uint> windowTypes;
+
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ switch (type) {
+ case Qt::Dialog:
+ case Qt::Sheet:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG));
+ break;
+ case Qt::Tool:
+ case Qt::Drawer:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY));
+ break;
+ case Qt::ToolTip:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
+ break;
+ case Qt::SplashScreen:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH));
+ break;
+ default:
+ break;
+ }
+
+ if (flags & Qt::FramelessWindowHint)
+ windowTypes.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL));
+
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32,
+ windowTypes.count(), windowTypes.constData()));
+}
+
+WId QXcbWindow::winId() const
+{
+ return m_window;
+}
+
+void QXcbWindow::setParent(const QPlatformWindow *parent)
+{
+ QPoint topLeft = geometry().topLeft();
+ Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
+}
+
+void QXcbWindow::setWindowTitle(const QString &title)
+{
+ QByteArray ba = title.toUtf8();
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_NET_WM_NAME),
+ atom(QXcbAtom::UTF8_STRING),
+ 8,
+ ba.length(),
+ ba.constData()));
+}
+
+void QXcbWindow::raise()
+{
+ const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
+ const quint32 values[] = { XCB_STACK_MODE_ABOVE };
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
+}
+
+void QXcbWindow::lower()
+{
+ const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
+ const quint32 values[] = { XCB_STACK_MODE_BELOW };
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
+}
+
+void QXcbWindow::requestActivateWindow()
+{
+ Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
+ connection()->sync();
+}
+
+QPlatformGLContext *QXcbWindow::glContext() 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)
+ 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
+ }
+ return m_context;
+}
+
+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());
+ }
+}
+
+void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *event)
+{
+ if (event->format == 32 && event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
+ if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
+ QWindowSystemInterface::handleCloseEvent(widget());
+ } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
+ xcb_client_message_event_t reply = *event;
+
+ reply.response_type = XCB_CLIENT_MESSAGE;
+ reply.window = m_screen->root();
+
+ 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");
+ }
+ m_syncValue.lo = event->data.data32[2];
+ m_syncValue.hi = event->data.data32[3];
+ }
+ }
+}
+
+void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
+{
+ int xpos = geometry().x();
+ int ypos = geometry().y();
+
+ if ((event->width == geometry().width() && event->height == geometry().height()) || event->x != 0 || event->y != 0) {
+ xpos = event->x;
+ ypos = event->y;
+ }
+
+ QRect rect(xpos, ypos, event->width, event->height);
+
+ if (rect == geometry())
+ return;
+
+ QPlatformWindow::setGeometry(rect);
+ QWindowSystemInterface::handleGeometryChange(widget(), rect);
+
+#if XCB_USE_DRI2
+ if (m_context)
+ static_cast<QDri2Context *>(m_context)->resize(rect.size());
+#endif
+}
+
+static Qt::MouseButtons translateMouseButtons(int s)
+{
+ Qt::MouseButtons ret = 0;
+ if (s & XCB_BUTTON_MASK_1)
+ ret |= Qt::LeftButton;
+ if (s & XCB_BUTTON_MASK_2)
+ ret |= Qt::MidButton;
+ if (s & XCB_BUTTON_MASK_3)
+ ret |= Qt::RightButton;
+ return ret;
+}
+
+static Qt::MouseButton translateMouseButton(xcb_button_t s)
+{
+ switch (s) {
+ case 1:
+ return Qt::LeftButton;
+ case 2:
+ return Qt::MidButton;
+ case 3:
+ return Qt::RightButton;
+ default:
+ return Qt::NoButton;
+ }
+}
+
+void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
+{
+ QPoint local(event->event_x, event->event_y);
+ QPoint global(event->root_x, event->root_y);
+
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+
+ if (event->detail >= 4 && event->detail <= 7) {
+ //logic borrowed from qapplication_x11.cpp
+ int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
+ bool hor = (((event->detail == 4 || event->detail == 5)
+ && (modifiers & Qt::AltModifier))
+ || (event->detail == 6 || event->detail == 7));
+
+ QWindowSystemInterface::handleWheelEvent(widget(), event->time,
+ local, global, delta, hor ? Qt::Horizontal : Qt::Vertical);
+ return;
+ }
+
+ handleMouseEvent(event->detail, event->state, event->time, local, global);
+}
+
+void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event)
+{
+ QPoint local(event->event_x, event->event_y);
+ QPoint global(event->root_x, event->root_y);
+
+ handleMouseEvent(event->detail, event->state, event->time, local, global);
+}
+
+void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
+{
+ QPoint local(event->event_x, event->event_y);
+ QPoint global(event->root_x, event->root_y);
+
+ handleMouseEvent(event->detail, event->state, event->time, local, global);
+}
+
+void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global)
+{
+ 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);
+}
+
+void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *)
+{
+ QWindowSystemInterface::handleEnterEvent(widget());
+}
+
+void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *)
+{
+ QWindowSystemInterface::handleLeaveEvent(widget());
+}
+
+void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
+{
+ QWindowSystemInterface::handleWindowActivated(widget());
+}
+
+void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
+{
+ QWindowSystemInterface::handleWindowActivated(0);
+}
+
+void QXcbWindow::updateSyncRequestCounter()
+{
+ if (m_screen->syncRequestSupported() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
+ Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
+ xcb_flush(xcb_connection());
+ connection()->sync();
+
+ m_syncValue.lo = 0;
+ m_syncValue.hi = 0;
+ }
+}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
new file mode 100644
index 0000000000..e049837253
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbwindow.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 QXCBWINDOW_H
+#define QXCBWINDOW_H
+
+#include <QtGui/QPlatformWindow>
+#include <QtGui/QPlatformWindowFormat>
+
+#include <xcb/xcb.h>
+#include <xcb/sync.h>
+
+#include "qxcbobject.h"
+
+class QXcbScreen;
+
+class QXcbWindow : public QXcbObject, public QPlatformWindow
+{
+public:
+ QXcbWindow(QWidget *tlw);
+ ~QXcbWindow();
+
+ void setGeometry(const QRect &rect);
+
+ void setVisible(bool visible);
+ Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ WId winId() const;
+ void setParent(const QPlatformWindow *window);
+
+ void setWindowTitle(const QString &title);
+ void raise();
+ void lower();
+
+ void requestActivateWindow();
+
+ QPlatformGLContext *glContext() const;
+
+ xcb_window_t window() const { return m_window; }
+
+ 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 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);
+
+ void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event);
+ void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event);
+ void handleFocusInEvent(const xcb_focus_in_event_t *event);
+ void handleFocusOutEvent(const xcb_focus_out_event_t *event);
+
+ void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global);
+
+ void updateSyncRequestCounter();
+
+private:
+ void setNetWmWindowTypes(Qt::WindowFlags flags);
+
+ QXcbScreen *m_screen;
+
+ xcb_window_t m_window;
+ QPlatformGLContext *m_context;
+
+ xcb_sync_int64_t m_syncValue;
+ xcb_sync_counter_t m_syncCounter;
+
+ bool m_hasReceivedSyncRequest;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
new file mode 100644
index 0000000000..718f09383c
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** 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 "qxcbwindowsurface.h"
+
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+#include "qxcbwindow.h"
+
+#include <xcb/shm.h>
+#include <xcb/xcb_image.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <stdio.h>
+
+#include <qdebug.h>
+
+class QXcbShmImage : public QXcbObject
+{
+public:
+ QXcbShmImage(QXcbScreen *connection, const QSize &size);
+ ~QXcbShmImage() { destroy(); }
+
+ QImage *image() { return &m_qimage; }
+
+ void put(xcb_window_t window, const QPoint &dst, const QRect &source);
+ void preparePaint(const QRegion &region);
+
+private:
+ void destroy();
+
+ xcb_shm_segment_info_t m_shm_info;
+
+ xcb_image_t *m_xcb_image;
+
+ QImage m_qimage;
+
+ xcb_gcontext_t m_gc;
+ xcb_window_t m_gc_window;
+
+ QRegion m_dirty;
+};
+
+QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
+ : QXcbObject(screen->connection())
+ , m_gc(0)
+ , m_gc_window(0)
+{
+ Q_XCB_NOOP(connection());
+ m_xcb_image = xcb_image_create_native(xcb_connection(),
+ size.width(),
+ size.height(),
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ screen->depth(),
+ 0,
+ ~0,
+ 0);
+
+ m_shm_info.shmid = shmget (IPC_PRIVATE,
+ m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777);
+
+ 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";
+
+ m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, screen->format());
+}
+
+void QXcbShmImage::destroy()
+{
+ 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 (m_gc)
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
+}
+
+void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
+{
+ Q_XCB_NOOP(connection());
+ if (m_gc_window != window) {
+ if (m_gc)
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
+
+ m_gc = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));
+
+ m_gc_window = window;
+ }
+
+ Q_XCB_NOOP(connection());
+ 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);
+ Q_XCB_NOOP(connection());
+
+ m_dirty = m_dirty | source;
+
+ xcb_flush(xcb_connection());
+ Q_XCB_NOOP(connection());
+}
+
+void QXcbShmImage::preparePaint(const QRegion &region)
+{
+ // to prevent X from reading from the image region while we're writing to it
+ if (m_dirty.intersects(region)) {
+ connection()->sync();
+ m_dirty = QRegion();
+ }
+}
+
+QXcbWindowSurface::QXcbWindowSurface(QWidget *widget, bool setDefaultSurface)
+ : QWindowSurface(widget, setDefaultSurface)
+ , m_image(0)
+ , m_syncingResize(false)
+{
+ QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+ setConnection(screen->connection());
+}
+
+QXcbWindowSurface::~QXcbWindowSurface()
+{
+ delete m_image;
+}
+
+QPaintDevice *QXcbWindowSurface::paintDevice()
+{
+ return m_image->image();
+}
+
+void QXcbWindowSurface::beginPaint(const QRegion &region)
+{
+ m_image->preparePaint(region);
+}
+
+void QXcbWindowSurface::endPaint(const QRegion &)
+{
+}
+
+void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ QRect bounds = region.boundingRect();
+
+ if (size().isEmpty() || !geometry().contains(bounds))
+ 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();
+
+ 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));
+
+ Q_XCB_NOOP(connection());
+
+ if (m_syncingResize) {
+ xcb_flush(xcb_connection());
+ connection()->sync();
+ m_syncingResize = false;
+ window->updateSyncRequestCounter();
+ }
+}
+
+void QXcbWindowSurface::resize(const QSize &size)
+{
+ if (size == QWindowSurface::size())
+ return;
+
+ Q_XCB_NOOP(connection());
+ QWindowSurface::resize(size);
+
+ QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window()));
+
+ delete m_image;
+ m_image = new QXcbShmImage(screen, size);
+ Q_XCB_NOOP(connection());
+
+ m_syncingResize = true;
+}
+
+extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
+
+bool QXcbWindowSurface::scroll(const QRegion &area, int dx, int dy)
+{
+ if (m_image->image()->isNull())
+ return false;
+
+ m_image->preparePaint(area);
+
+ const QVector<QRect> rects = area.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ qt_scrollRectInImage(*m_image->image(), rects.at(i), QPoint(dx, dy));
+
+ return true;
+}
+
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.h b/src/plugins/platforms/xcb/qxcbwindowsurface.h
new file mode 100644
index 0000000000..23d32ef445
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbwindowsurface.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$
+** 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 QXCBWINDOWSURFACE_H
+#define QXCBWINDOWSURFACE_H
+
+#include <private/qwindowsurface_p.h>
+
+#include <xcb/xcb.h>
+
+#include "qxcbobject.h"
+
+class QXcbShmImage;
+
+class QXcbWindowSurface : public QXcbObject, public QWindowSurface
+{
+public:
+ QXcbWindowSurface(QWidget *widget, bool setDefaultSurface = true);
+ ~QXcbWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size);
+ bool scroll(const QRegion &area, int dx, int dy);
+
+ void beginPaint(const QRegion &);
+ void endPaint(const QRegion &);
+
+private:
+ QXcbShmImage *m_image;
+ bool m_syncingResize;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
new file mode 100644
index 0000000000..101bdcd3c1
--- /dev/null
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -0,0 +1,70 @@
+TARGET = xcb
+
+include(../../qpluginbase.pri)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+SOURCES = \
+ qxcbconnection.cpp \
+ qxcbintegration.cpp \
+ qxcbkeyboard.cpp \
+ qxcbscreen.cpp \
+ qxcbwindow.cpp \
+ qxcbwindowsurface.cpp \
+ main.cpp \
+ qxcbnativeinterface.cpp
+
+HEADERS = \
+ qxcbconnection.h \
+ qxcbintegration.h \
+ qxcbkeyboard.h \
+ qxcbobject.h \
+ qxcbscreen.h \
+ qxcbwindow.h \
+ qxcbwindowsurface.h \
+ qxcbnativeinterface.h
+
+contains(QT_CONFIG, opengl) {
+ QT += opengl
+
+# 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
+ }
+ }
+}
+
+LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync
+
+include (../fontdatabases/genericunix/genericunix.pri)
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/xlib/main.cpp b/src/plugins/platforms/xlib/main.cpp
new file mode 100644
index 0000000000..f0bf6ff1c9
--- /dev/null
+++ b/src/plugins/platforms/xlib/main.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 <QtGui/QPlatformIntegrationPlugin>
+#include "qxlibintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXlibIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QXlibIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "Xlib";
+#ifndef QT_NO_OPENGL
+ list << "XlibGL";
+#endif
+ return list;
+}
+
+QPlatformIntegration* QXlibIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ 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;
+}
+
+Q_EXPORT_PLUGIN2(xlib, QXlibIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp
new file mode 100644
index 0000000000..7a0f36dc99
--- /dev/null
+++ b/src/plugins/platforms/xlib/qglxintegration.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** 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 <QDebug>
+#include <QLibrary>
+#include <QGLFormat>
+
+#include "qxlibwindow.h"
+#include "qxlibscreen.h"
+#include "qxlibdisplay.h"
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+#include "qglxconvenience.h"
+
+#include "qglxintegration.h"
+
+#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
+#include <dlfcn.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QGLXContext::QGLXContext(Window window, QXlibScreen *screen, const QPlatformWindowFormat &format)
+ : QPlatformGLContext()
+ , 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();
+
+ 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);
+
+#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) {
+ qDebug("Destroying GLX context 0x%p", m_context);
+ glXDestroyContext(m_screen->display()->nativeDisplay(), m_context);
+ }
+}
+
+void QGLXContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+#ifdef MYX11_DEBUG
+ qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", m_drawable, m_context);
+#endif
+ glXMakeCurrent(m_screen->display()->nativeDisplay(), m_drawable, m_context);
+}
+
+void QGLXContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ glXMakeCurrent(m_screen->display()->nativeDisplay(), 0, 0);
+}
+
+void QGLXContext::swapBuffers()
+{
+ glXSwapBuffers(m_screen->display()->nativeDisplay(), m_drawable);
+}
+
+void* QGLXContext::getProcAddress(const QString& procName)
+{
+ typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
+ static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
+ static bool resolved = false;
+
+ if (resolved && !glXGetProcAddressARB)
+ return 0;
+ if (!glXGetProcAddressARB) {
+ QList<QByteArray> glxExt = QByteArray(glXGetClientString(m_screen->display()->nativeDisplay(), GLX_EXTENSIONS)).split(' ');
+ if (glxExt.contains("GLX_ARB_get_proc_address")) {
+#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
+ void *handle = dlopen(NULL, RTLD_LAZY);
+ if (handle) {
+ glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
+ dlclose(handle);
+ }
+ if (!glXGetProcAddressARB)
+#endif
+ {
+ extern const QString qt_gl_library_name();
+// QLibrary lib(qt_gl_library_name());
+ QLibrary lib(QLatin1String("GL"));
+ glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
+ }
+ }
+ resolved = true;
+ }
+ if (!glXGetProcAddressARB)
+ return 0;
+ return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data()));
+}
+
+QPlatformWindowFormat QGLXContext::platformWindowFormat() const
+{
+ return m_windowFormat;
+}
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
diff --git a/src/plugins/platforms/xlib/qglxintegration.h b/src/plugins/platforms/xlib/qglxintegration.h
new file mode 100644
index 0000000000..57c716bef0
--- /dev/null
+++ b/src/plugins/platforms/xlib/qglxintegration.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 Q_GLX_CONTEXT_H
+#define Q_GLX_CONTEXT_H
+
+#include "qxlibwindow.h"
+
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformWindowFormat>
+
+#include <QtCore/QMutex>
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+#include <GL/glx.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGLXContext : public QPlatformGLContext
+{
+public:
+ QGLXContext(Window window, QXlibScreen *xd, const QPlatformWindowFormat &format);
+ ~QGLXContext();
+
+ virtual void makeCurrent();
+ virtual void doneCurrent();
+ virtual void swapBuffers();
+ virtual void* getProcAddress(const QString& procName);
+
+ GLXContext glxContext() const {return m_context;}
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+private:
+ QXlibScreen *m_screen;
+ Drawable m_drawable;
+ GLXContext m_context;
+ QPlatformWindowFormat m_windowFormat;
+
+ QGLXContext (QXlibScreen *screen, Drawable drawable, GLXContext context);
+};
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+
+#endif
diff --git a/src/plugins/platforms/xlib/qxlibclipboard.cpp b/src/plugins/platforms/xlib/qxlibclipboard.cpp
new file mode 100644
index 0000000000..dfaf552121
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibclipboard.cpp
@@ -0,0 +1,677 @@
+/****************************************************************************
+**
+** 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 "qxlibclipboard.h"
+
+#include "qxlibscreen.h"
+#include "qxlibmime.h"
+#include "qxlibdisplay.h"
+
+#include <private/qapplication_p.h>
+
+#include <QtCore/QDebug>
+
+class QXlibClipboardMime : public QXlibMime
+{
+ Q_OBJECT
+public:
+ QXlibClipboardMime(QClipboard::Mode mode, QXlibClipboard *clipboard)
+ : QXlibMime()
+ , m_clipboard(clipboard)
+ {
+ switch (mode) {
+ case QClipboard::Selection:
+ modeAtom = XA_PRIMARY;
+ break;
+
+ case QClipboard::Clipboard:
+ modeAtom = QXlibStatic::atom(QXlibStatic::CLIPBOARD);
+ break;
+
+ default:
+ qWarning("QTestLiteMime: Internal error: Unsupported clipboard mode");
+ break;
+ }
+ }
+
+protected:
+ QStringList formats_sys() const
+ {
+ if (empty())
+ return QStringList();
+
+ if (!formatList.count()) {
+ QXlibClipboardMime *that = const_cast<QXlibClipboardMime *>(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,QXlibStatic::atom(QXlibStatic::TARGETS));
+
+ if (format_atoms.size() > 0) {
+ Atom *targets = (Atom *) format_atoms.data();
+ int size = format_atoms.size() / sizeof(Atom);
+
+ for (int i = 0; i < size; ++i) {
+ if (targets[i] == 0)
+ continue;
+
+ QStringList formatsForAtom = mimeFormatsForAtom(m_clipboard->screen()->display()->nativeDisplay(),targets[i]);
+ for (int j = 0; j < formatsForAtom.size(); ++j) {
+ if (!formatList.contains(formatsForAtom.at(j)))
+ that->formatList.append(formatsForAtom.at(j));
+ }
+ }
+ }
+ }
+
+ 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<Atom> atoms;
+ Atom *targets = (Atom *) format_atoms.data();
+ int size = format_atoms.size() / sizeof(Atom);
+ for (int i = 0; i < size; ++i)
+ atoms.append(targets[i]);
+
+ QByteArray encoding;
+ Atom fmtatom = mimeAtomForFormat(m_clipboard->screen()->display()->nativeDisplay(),fmt, requestedType, atoms, &encoding);
+
+ if (fmtatom == 0)
+ return QVariant();
+
+ return mimeConvertToFormat(m_clipboard->screen()->display()->nativeDisplay(),fmtatom, m_clipboard->getDataInFormat(modeAtom,fmtatom), fmt, requestedType, encoding);
+ }
+private:
+ bool empty() const
+ {
+ Window win = XGetSelectionOwner(m_clipboard->screen()->display()->nativeDisplay(), modeAtom);
+
+ return win == XNone;
+ }
+
+
+ Atom modeAtom;
+ QXlibClipboard *m_clipboard;
+ QStringList formatList;
+ QByteArray format_atoms;
+};
+
+const int QXlibClipboard::clipboard_timeout = 5000;
+
+QXlibClipboard::QXlibClipboard(QXlibScreen *screen)
+ : QPlatformClipboard()
+ , m_screen(screen)
+ , m_xClipboard(0)
+ , m_clientClipboard(0)
+ , m_xSelection(0)
+ , m_clientSelection(0)
+ , m_requestor(XNone)
+ , m_owner(XNone)
+{
+}
+
+const QMimeData * QXlibClipboard::mimeData(QClipboard::Mode mode) const
+{
+ if (mode == QClipboard::Clipboard) {
+ if (!m_xClipboard) {
+ QXlibClipboard *that = const_cast<QXlibClipboard *>(this);
+ that->m_xClipboard = new QXlibClipboardMime(mode,that);
+ }
+ Window clipboardOwner = XGetSelectionOwner(screen()->display()->nativeDisplay(),QXlibStatic::atom(QXlibStatic::CLIPBOARD));
+ if (clipboardOwner == owner()) {
+ return m_clientClipboard;
+ } else {
+ return m_xClipboard;
+ }
+ } else if (mode == QClipboard::Selection) {
+ if (!m_xSelection) {
+ QXlibClipboard *that = const_cast<QXlibClipboard *>(this);
+ that->m_xSelection = new QXlibClipboardMime(mode,that);
+ }
+ Window clipboardOwner = XGetSelectionOwner(screen()->display()->nativeDisplay(),XA_PRIMARY);
+ if (clipboardOwner == owner()) {
+ return m_clientSelection;
+ } else {
+ return m_xSelection;
+ }
+ }
+ return 0;
+}
+
+void QXlibClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
+{
+ Atom modeAtom;
+ QMimeData **d;
+ switch (mode) {
+ case QClipboard::Selection:
+ modeAtom = XA_PRIMARY;
+ d = &m_clientSelection;
+ break;
+
+ case QClipboard::Clipboard:
+ modeAtom = QXlibStatic::atom(QXlibStatic::CLIPBOARD);
+ d = &m_clientClipboard;
+ break;
+
+ default:
+ qWarning("QClipboard::setMimeData: unsupported mode '%d'", mode);
+ return;
+ }
+
+ Window newOwner;
+
+ if (! data) { // no data, clear clipboard contents
+ newOwner = XNone;
+ } else {
+ newOwner = owner();
+
+ *d = data;
+ }
+
+ XSetSelectionOwner(m_screen->display()->nativeDisplay(), modeAtom, newOwner, CurrentTime);
+
+ if (XGetSelectionOwner(m_screen->display()->nativeDisplay(), modeAtom) != newOwner) {
+ qWarning("QClipboard::setData: Cannot set X11 selection owner");
+ }
+
+}
+
+bool QXlibClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ if (mode == QClipboard::Clipboard || mode == QClipboard::Selection)
+ return true;
+ return false;
+}
+
+
+QXlibScreen * QXlibClipboard::screen() const
+{
+ return m_screen;
+}
+
+Window QXlibClipboard::requestor() const
+{
+ if (!m_requestor) {
+ int x = 0, y = 0, w = 3, h = 3;
+ QXlibClipboard *that = const_cast<QXlibClipboard *>(this);
+ Window window = XCreateSimpleWindow(m_screen->display()->nativeDisplay(), m_screen->rootWindow(),
+ x, y, w, h, 0 /*border_width*/,
+ m_screen->blackPixel(), m_screen->whitePixel());
+ that->setRequestor(window);
+ }
+ return m_requestor;
+}
+
+void QXlibClipboard::setRequestor(Window window)
+{
+ if (m_requestor != XNone) {
+ XDestroyWindow(m_screen->display()->nativeDisplay(),m_requestor);
+ }
+ m_requestor = window;
+}
+
+Window QXlibClipboard::owner() const
+{
+ if (!m_owner) {
+ int x = 0, y = 0, w = 3, h = 3;
+ QXlibClipboard *that = const_cast<QXlibClipboard *>(this);
+ Window window = XCreateSimpleWindow(m_screen->display()->nativeDisplay(), m_screen->rootWindow(),
+ x, y, w, h, 0 /*border_width*/,
+ m_screen->blackPixel(), m_screen->whitePixel());
+ that->setOwner(window);
+ }
+ return m_owner;
+}
+
+void QXlibClipboard::setOwner(Window window)
+{
+ if (m_owner != XNone){
+ XDestroyWindow(m_screen->display()->nativeDisplay(),m_owner);
+ }
+ m_owner = window;
+}
+
+Atom QXlibClipboard::sendTargetsSelection(QMimeData *d, Window window, Atom property)
+{
+ QVector<Atom> types;
+ QStringList formats = QInternalMimeData::formatsHelper(d);
+ for (int i = 0; i < formats.size(); ++i) {
+ QList<Atom> atoms = QXlibMime::mimeAtomsForFormat(screen()->display()->nativeDisplay(),formats.at(i));
+ for (int j = 0; j < atoms.size(); ++j) {
+ if (!types.contains(atoms.at(j)))
+ types.append(atoms.at(j));
+ }
+ }
+ types.append(QXlibStatic::atom(QXlibStatic::TARGETS));
+ types.append(QXlibStatic::atom(QXlibStatic::MULTIPLE));
+ types.append(QXlibStatic::atom(QXlibStatic::TIMESTAMP));
+ types.append(QXlibStatic::atom(QXlibStatic::SAVE_TARGETS));
+
+ XChangeProperty(screen()->display()->nativeDisplay(), window, property, XA_ATOM, 32,
+ PropModeReplace, (uchar *) types.data(), types.size());
+ return property;
+}
+
+Atom QXlibClipboard::sendSelection(QMimeData *d, Atom target, Window window, Atom property)
+{
+ Atom atomFormat = target;
+ int dataFormat = 0;
+ QByteArray data;
+
+ QString fmt = QXlibMime::mimeAtomToString(screen()->display()->nativeDisplay(), target);
+ if (fmt.isEmpty()) { // Not a MIME type we have
+ qDebug() << "QClipboard: send_selection(): converting to type '%s' is not supported" << fmt.data();
+ return XNone;
+ }
+ qDebug() << "QClipboard: send_selection(): converting to type '%s'" << fmt.data();
+
+ if (QXlibMime::mimeDataForAtom(screen()->display()->nativeDisplay(),target, d, &data, &atomFormat, &dataFormat)) {
+
+ // don't allow INCR transfers when using MULTIPLE or to
+ // Motif clients (since Motif doesn't support INCR)
+ static Atom motif_clip_temporary = QXlibStatic::atom(QXlibStatic::CLIP_TEMPORARY);
+ bool allow_incr = property != motif_clip_temporary;
+
+ // X_ChangeProperty protocol request is 24 bytes
+ const int increment = (XMaxRequestSize(screen()->display()->nativeDisplay()) * 4) - 24;
+ if (data.size() > increment && allow_incr) {
+ long bytes = data.size();
+ XChangeProperty(screen()->display()->nativeDisplay(), window, property,
+ QXlibStatic::atom(QXlibStatic::INCR), 32, PropModeReplace, (uchar *) &bytes, 1);
+
+// (void)new QClipboardINCRTransaction(window, property, atomFormat, dataFormat, data, increment);
+ qDebug() << "not implemented INCRT just YET!";
+ return property;
+ }
+
+ // make sure we can perform the XChangeProperty in a single request
+ if (data.size() > increment)
+ return XNone; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
+ int dataSize = data.size() / (dataFormat / 8);
+ // use a single request to transfer data
+ XChangeProperty(screen()->display()->nativeDisplay(), window, property, atomFormat,
+ dataFormat, PropModeReplace, (uchar *) data.data(),
+ dataSize);
+ }
+ return property;
+}
+
+void QXlibClipboard::handleSelectionRequest(XEvent *xevent)
+{
+ XSelectionRequestEvent *req = &xevent->xselectionrequest;
+
+ if (requestor() && req->requestor == requestor()) {
+ qDebug() << "This should be caught before";
+ return;
+ }
+
+ XEvent event;
+ event.xselection.type = SelectionNotify;
+ event.xselection.display = req->display;
+ event.xselection.requestor = req->requestor;
+ event.xselection.selection = req->selection;
+ event.xselection.target = req->target;
+ event.xselection.property = XNone;
+ event.xselection.time = req->time;
+
+ QMimeData *d;
+ if (req->selection == XA_PRIMARY) {
+ d = m_clientSelection;
+ } else if (req->selection == QXlibStatic::atom(QXlibStatic::CLIPBOARD)) {
+ d = m_clientClipboard;
+ } else {
+ qWarning("QClipboard: Unknown selection '%lx'", req->selection);
+ XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &event);
+ return;
+ }
+
+ if (!d) {
+ qWarning("QClipboard: Cannot transfer data, no data available");
+ XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &event);
+ return;
+ }
+
+ Atom xa_targets = QXlibStatic::atom(QXlibStatic::TARGETS);
+ Atom xa_multiple = QXlibStatic::atom(QXlibStatic::MULTIPLE);
+ Atom xa_timestamp = QXlibStatic::atom(QXlibStatic::TIMESTAMP);
+
+ struct AtomPair { Atom target; Atom property; } *multi = 0;
+ Atom multi_type = XNone;
+ 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 == XNone
+ || !clipboardReadProperty(req->requestor, req->property, false, &multi_data,
+ 0, &multi_type, &multi_format)
+ || multi_format != 32) {
+ // MULTIPLE property not formatted correctly
+ XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &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) {
+ Atom target;
+ Atom property;
+
+ if (multi) {
+ target = multi[imulti].target;
+ property = multi[imulti].property;
+ } else {
+ target = req->target;
+ property = req->property;
+ if (property == XNone) // obsolete client
+ property = target;
+ }
+
+ Atom ret = XNone;
+ if (target == XNone || property == XNone) {
+ ;
+ } else if (target == xa_timestamp) {
+// if (d->timestamp != CurrentTime) {
+// XChangeProperty(screen()->display()->nativeDisplay(), req->requestor, property, XA_INTEGER, 32,
+// PropModeReplace, CurrentTime, 1);
+// 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 == XNone) {
+ multi[imulti].property = XNone;
+ multi_writeback = true;
+ }
+ } else {
+ event.xselection.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
+ XChangeProperty(screen()->display()->nativeDisplay(), req->requestor, req->property, multi_type, 32,
+ PropModeReplace, (uchar *) multi, nmulti * 2);
+ }
+
+ delete [] multi;
+ event.xselection.property = req->property;
+ }
+
+ // send selection notify to requestor
+ XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &event);
+}
+
+static inline int maxSelectionIncr(Display *dpy)
+{ return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; }
+
+bool QXlibClipboard::clipboardReadProperty(Window win, Atom property, bool deleteProperty, QByteArray *buffer, int *size, Atom *type, int *format) const
+{
+ int maxsize = maxSelectionIncr(screen()->display()->nativeDisplay());
+ ulong bytes_left; // bytes_after
+ ulong length; // nitems
+ uchar *data;
+ Atom dummy_type;
+ int dummy_format;
+ int r;
+
+ 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
+ r = XGetWindowProperty(screen()->display()->nativeDisplay(), win, property, 0, 0, False,
+ AnyPropertyType, type, format,
+ &length, &bytes_left, &data);
+ if (r != Success || (type && *type == XNone)) {
+ buffer->resize(0);
+ return false;
+ }
+ XFree((char*)data);
+
+ 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...
+
+ r = XGetWindowProperty(screen()->display()->nativeDisplay(), win, property, offset, maxsize/4,
+ False, AnyPropertyType, type, format,
+ &length, &bytes_left, &data);
+ if (r != Success || (type && *type == XNone))
+ break;
+
+ 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;
+
+ XFree((char*)data);
+ }
+
+ if (*format == 8 && *type == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) {
+ // convert COMPOUND_TEXT to a multibyte string
+ XTextProperty textprop;
+ textprop.encoding = *type;
+ textprop.format = *format;
+ textprop.nitems = buffer_offset;
+ textprop.value = (unsigned char *) buffer->data();
+
+ char **list_ret = 0;
+ int count;
+ if (XmbTextPropertyToTextList(screen()->display()->nativeDisplay(), &textprop, &list_ret,
+ &count) == Success && count && list_ret) {
+ offset = buffer_offset = strlen(list_ret[0]);
+ buffer->resize(offset);
+ memcpy(buffer->data(), list_ret[0], offset);
+ }
+ if (list_ret) XFreeStringList(list_ret);
+ }
+ }
+
+ // correct size, not 0-term.
+ if (size)
+ *size = buffer_offset;
+
+ if (deleteProperty)
+ XDeleteProperty(screen()->display()->nativeDisplay(), win, property);
+
+ screen()->display()->flush();
+
+ return ok;
+}
+
+QByteArray QXlibClipboard::clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm)
+{
+ XEvent event;
+
+ 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 (;;) {
+ screen()->display()->flush();
+ if (!screen()->waitForClipboardEvent(win,PropertyNotify,&event,clipboard_timeout))
+ break;
+ if (event.xproperty.atom != property ||
+ event.xproperty.state != PropertyNewValue)
+ 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;
+ }
+ }
+
+ // 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 QXlibClipboard::getDataInFormat(Atom modeAtom, Atom fmtatom)
+{
+ QByteArray buf;
+
+ Window win = requestor();
+
+ XSelectInput(screen()->display()->nativeDisplay(), win, NoEventMask); // don't listen for any events
+
+ XDeleteProperty(screen()->display()->nativeDisplay(), win, QXlibStatic::atom(QXlibStatic::_QT_SELECTION));
+ XConvertSelection(screen()->display()->nativeDisplay(), modeAtom, fmtatom, QXlibStatic::atom(QXlibStatic::_QT_SELECTION), win, CurrentTime);
+ screen()->display()->sync();
+
+ XEvent xevent;
+ if (!screen()->waitForClipboardEvent(win,SelectionNotify,&xevent,clipboard_timeout) ||
+ xevent.xselection.property == XNone) {
+ return buf;
+ }
+
+ Atom type;
+ XSelectInput(screen()->display()->nativeDisplay(), win, PropertyChangeMask);
+
+ if (clipboardReadProperty(win, QXlibStatic::atom(QXlibStatic::_QT_SELECTION), true, &buf, 0, &type, 0)) {
+ if (type == QXlibStatic::atom(QXlibStatic::INCR)) {
+ int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
+ buf = clipboardReadIncrementalProperty(win, QXlibStatic::atom(QXlibStatic::_QT_SELECTION), nbytes, false);
+ }
+ }
+
+ XSelectInput(screen()->display()->nativeDisplay(), win, NoEventMask);
+
+
+ return buf;
+}
+
+#include "qxlibclipboard.moc"
diff --git a/src/plugins/platforms/xlib/qxlibclipboard.h b/src/plugins/platforms/xlib/qxlibclipboard.h
new file mode 100644
index 0000000000..15901b0d2a
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibclipboard.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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 QTESTLITECLIPBOARD_H
+#define QTESTLITECLIPBOARD_H
+
+#include <QPlatformClipboard>
+#include "qxlibstatic.h"
+
+class QXlibScreen;
+class QXlibClipboard : public QPlatformClipboard
+{
+public:
+ QXlibClipboard(QXlibScreen *screen);
+
+ const QMimeData *mimeData(QClipboard::Mode mode) const;
+ void setMimeData(QMimeData *data, QClipboard::Mode mode);
+
+ bool supportsMode(QClipboard::Mode mode) const;
+
+ QXlibScreen *screen() const;
+
+ Window requestor() const;
+ void setRequestor(Window window);
+
+ Window owner() const;
+
+ void handleSelectionRequest(XEvent *event);
+
+ bool clipboardReadProperty(Window win, Atom property, bool deleteProperty, QByteArray *buffer, int *size, Atom *type, int *format) const;
+ QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm);
+
+ QByteArray getDataInFormat(Atom modeAtom, Atom fmtatom);
+
+private:
+ void setOwner(Window window);
+
+ Atom sendTargetsSelection(QMimeData *d, Window window, Atom property);
+ Atom sendSelection(QMimeData *d, Atom target, Window window, Atom property);
+
+ QXlibScreen *m_screen;
+
+ QMimeData *m_xClipboard;
+ QMimeData *m_clientClipboard;
+
+ QMimeData *m_xSelection;
+ QMimeData *m_clientSelection;
+
+ Window m_requestor;
+ Window m_owner;
+
+ static const int clipboard_timeout;
+
+};
+
+#endif // QTESTLITECLIPBOARD_H
diff --git a/src/plugins/platforms/xlib/qxlibcursor.cpp b/src/plugins/platforms/xlib/qxlibcursor.cpp
new file mode 100644
index 0000000000..042cbc9933
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibcursor.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** 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 "qxlibcursor.h"
+
+#include "qxlibintegration.h"
+#include "qxlibscreen.h"
+#include "qxlibwindow.h"
+#include "qxlibdisplay.h"
+
+#include <QtGui/QBitmap>
+
+#include <X11/cursorfont.h>
+
+QT_BEGIN_NAMESPACE
+
+QXlibCursor::QXlibCursor(QXlibScreen *screen)
+ : QPlatformCursor(screen)
+{
+}
+
+void QXlibCursor::changeCursor(QCursor *cursor, QWidget *widget)
+{
+ QXlibWindow *w = 0;
+ if (widget) {
+ QWidget *window = widget->window();
+ w = static_cast<QXlibWindow*>(window->platformWindow());
+ } else {
+ // No X11 cursor control when there is no widget under the cursor
+ return;
+ }
+
+ if (!w)
+ return;
+
+ int id = cursor->handle();
+
+ Cursor c;
+ if (!cursorMap.contains(id)) {
+ if (cursor->shape() == Qt::BitmapCursor)
+ c = createCursorBitmap(cursor);
+ else
+ c = createCursorShape(cursor->shape());
+ if (!c) {
+ return;
+ }
+ cursorMap.insert(id, c);
+ } else {
+ c = cursorMap.value(id);
+ }
+
+ w->setCursor(c);
+}
+
+Cursor QXlibCursor::createCursorBitmap(QCursor * cursor)
+{
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ QPoint spot = cursor->hotSpot();
+ Window rootwin = testLiteScreen()->rootWindow();
+
+ QImage mapImage = cursor->bitmap()->toImage().convertToFormat(QImage::Format_MonoLSB);
+ QImage maskImage = cursor->mask()->toImage().convertToFormat(QImage::Format_MonoLSB);
+
+ int width = cursor->bitmap()->width();
+ int height = cursor->bitmap()->height();
+ int bytesPerLine = mapImage.bytesPerLine();
+ int destLineSize = width / 8;
+ if (width % 8)
+ destLineSize++;
+
+ const uchar * map = mapImage.bits();
+ const uchar * mask = maskImage.bits();
+
+ char * mapBits = new char[height * destLineSize];
+ char * maskBits = new char[height * destLineSize];
+ for (int i = 0; i < height; i++) {
+ memcpy(mapBits + (destLineSize * i),map + (bytesPerLine * i), destLineSize);
+ memcpy(maskBits + (destLineSize * i),mask + (bytesPerLine * i), destLineSize);
+ }
+
+ Pixmap cp = XCreateBitmapFromData(testLiteScreen()->display()->nativeDisplay(), rootwin, mapBits, width, height);
+ Pixmap mp = XCreateBitmapFromData(testLiteScreen()->display()->nativeDisplay(), rootwin, maskBits, width, height);
+ Cursor c = XCreatePixmapCursor(testLiteScreen()->display()->nativeDisplay(), cp, mp, &fg, &bg, spot.x(), spot.y());
+ XFreePixmap(testLiteScreen()->display()->nativeDisplay(), cp);
+ XFreePixmap(testLiteScreen()->display()->nativeDisplay(), mp);
+ delete[] mapBits;
+ delete[] maskBits;
+
+ return c;
+}
+
+Cursor QXlibCursor::createCursorShape(int cshape)
+{
+ Cursor cursor = 0;
+
+ if (cshape < 0 || cshape > Qt::LastCursor)
+ return 0;
+
+ switch (cshape) {
+ case Qt::ArrowCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_left_ptr);
+ break;
+ case Qt::UpArrowCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_center_ptr);
+ break;
+ case Qt::CrossCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_crosshair);
+ break;
+ case Qt::WaitCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_watch);
+ break;
+ case Qt::IBeamCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_xterm);
+ break;
+ case Qt::SizeAllCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_fleur);
+ break;
+ case Qt::PointingHandCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_hand2);
+ break;
+ case Qt::SizeBDiagCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_top_right_corner);
+ break;
+ case Qt::SizeFDiagCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_bottom_right_corner);
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_sb_v_double_arrow);
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_sb_h_double_arrow);
+ break;
+ case Qt::WhatsThisCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_question_arrow);
+ break;
+ case Qt::ForbiddenCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_circle);
+ break;
+ case Qt::BusyCursor:
+ cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_watch);
+ break;
+
+ default: //default cursor for all the rest
+ break;
+ }
+ return cursor;
+}
+
+QXlibScreen * QXlibCursor::testLiteScreen() const
+{
+ return static_cast<QXlibScreen *>(screen);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibcursor.h b/src/plugins/platforms/xlib/qxlibcursor.h
new file mode 100644
index 0000000000..62b13eb36b
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibcursor.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 QTESTLITECURSOR_H
+#define QTESTLITECURSOR_H
+
+#include <QtGui/QPlatformCursor>
+
+#include "qxlibintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXlibCursor : QPlatformCursor
+{
+public:
+ QXlibCursor(QXlibScreen *screen);
+
+ void changeCursor(QCursor * cursor, QWidget * widget);
+private:
+
+ Cursor createCursorBitmap(QCursor * cursor);
+ Cursor createCursorShape(int cshape);
+
+ QXlibScreen *testLiteScreen() const;
+ QMap<int, Cursor> cursorMap;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTESTLITECURSOR_H
diff --git a/src/plugins/platforms/xlib/qxlibdisplay.cpp b/src/plugins/platforms/xlib/qxlibdisplay.cpp
new file mode 100644
index 0000000000..d8aa2309fb
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibdisplay.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 "qxlibdisplay.h"
+
+QXlibDisplay::QXlibDisplay(Display *display)
+ : mDisplay(display)
+{
+ if (!mDisplay) {
+ qFatal("Cannot connect to X server");
+ }
+ mDisplayName = QString::fromLocal8Bit(DisplayString(mDisplay));
+}
+
+QXlibDisplay::~QXlibDisplay()
+{
+ XCloseDisplay(mDisplay);
+}
+
+QString QXlibDisplay::displayName() const
+{
+ { return mDisplayName; }
+}
+
+
+
+Display * QXlibDisplay::nativeDisplay() const
+{
+ return mDisplay;
+}
+
+void QXlibDisplay::sync() const
+{
+ XSync(mDisplay, False);
+}
+
+void QXlibDisplay::flush() const
+{
+ XFlush(mDisplay);
+}
diff --git a/src/plugins/platforms/xlib/qxlibdisplay.h b/src/plugins/platforms/xlib/qxlibdisplay.h
new file mode 100644
index 0000000000..557ab522a1
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibdisplay.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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 QXLIBDISPLAY_H
+#define QXLIBDISPLAY_H
+
+#include "qxlibintegration.h"
+
+class QXlibDisplay
+{
+public:
+ QXlibDisplay(Display *display);
+ ~QXlibDisplay();
+ QString displayName() const;
+
+ Display *nativeDisplay() const;
+
+ void sync() const;
+ void flush() const;
+private:
+ Display *mDisplay;
+ QString mDisplayName;
+};
+
+#endif // QXLIBDISPLAY_H
diff --git a/src/plugins/platforms/xlib/qxlibintegration.cpp b/src/plugins/platforms/xlib/qxlibintegration.cpp
new file mode 100644
index 0000000000..78f907abd2
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibintegration.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** 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 "qxlibintegration.h"
+#include "qxlibwindowsurface.h"
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtCore/qdebug.h>
+
+#include "qxlibwindow.h"
+#include "qgenericunixfontdatabase.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
+
+QT_BEGIN_NAMESPACE
+
+QXlibIntegration::QXlibIntegration(bool useOpenGL)
+ : mUseOpenGL(useOpenGL)
+ , mFontDb(new QGenericUnixFontDatabase())
+ , mClipboard(0)
+ , mNativeInterface(new QXlibNativeInterface)
+{
+ mPrimaryScreen = new QXlibScreen();
+ mScreens.append(mPrimaryScreen);
+}
+
+bool QXlibIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return hasOpenGL();
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPixmapData *QXlibIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+#ifndef QT_NO_OPENGL
+ if (mUseOpenGL)
+ return new QGLPixmapData(type);
+#endif
+ return new QRasterPixmapData(type);
+}
+
+QWindowSurface *QXlibIntegration::createWindowSurface(QWidget *widget, WId) const
+{
+#ifndef QT_NO_OPENGL
+ if (mUseOpenGL)
+ return new QGLWindowSurface(widget);
+#endif
+ return new QXlibWindowSurface(widget);
+}
+
+
+QPlatformWindow *QXlibIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
+{
+ return new QXlibWindow(widget);
+}
+
+
+
+QPixmap QXlibIntegration::grabWindow(WId window, int x, int y, int width, int height) 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);
+}
+
+QPlatformFontDatabase *QXlibIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
+QPlatformClipboard * QXlibIntegration::clipboard() const
+{
+ //Use lazy init since clipboard needs QTestliteScreen
+ if (!mClipboard) {
+ QXlibIntegration *that = const_cast<QXlibIntegration *>(this);
+ that->mClipboard = new QXlibClipboard(mPrimaryScreen);
+ }
+ return mClipboard;
+}
+
+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<const 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
new file mode 100644
index 0000000000..1a2515a08d
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibintegration.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$
+** 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 QGRAPHICSSYSTEM_TESTLITE_H
+#define QGRAPHICSSYSTEM_TESTLITE_H
+
+//make sure textstream is included before any X11 headers
+#include <QtCore/QTextStream>
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+#include <QtGui/QPlatformNativeInterface>
+
+#include "qxlibstatic.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXlibScreen;
+
+class QXlibIntegration : public QPlatformIntegration
+{
+public:
+ QXlibIntegration(bool useOpenGL = false);
+
+ 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;
+
+ QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+
+ QList<QPlatformScreen *> screens() const { return mScreens; }
+
+ QPlatformFontDatabase *fontDatabase() const;
+ QPlatformClipboard *clipboard() const;
+
+ QPlatformNativeInterface *nativeInterface() const;
+
+private:
+ bool hasOpenGL() const;
+
+ bool mUseOpenGL;
+ QXlibScreen *mPrimaryScreen;
+ QList<QPlatformScreen *> mScreens;
+ QPlatformFontDatabase *mFontDb;
+ QPlatformClipboard *mClipboard;
+ QPlatformNativeInterface *mNativeInterface;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.cpp b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
new file mode 100644
index 0000000000..8d94157e08
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
@@ -0,0 +1,1001 @@
+/****************************************************************************
+**
+** 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 "qxlibkeyboard.h"
+
+#include "qxlibscreen.h"
+#include "qxlibdisplay.h"
+
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QTextCodec>
+
+#ifndef XK_ISO_Left_Tab
+#define XK_ISO_Left_Tab 0xFE20
+#endif
+
+#ifndef XK_dead_hook
+#define XK_dead_hook 0xFE61
+#endif
+
+#ifndef XK_dead_horn
+#define XK_dead_horn 0xFE62
+#endif
+
+#ifndef XK_Codeinput
+#define XK_Codeinput 0xFF37
+#endif
+
+#ifndef XK_Kanji_Bangou
+#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */
+#endif
+
+// Fix old X libraries
+#ifndef XK_KP_Home
+#define XK_KP_Home 0xFF95
+#endif
+#ifndef XK_KP_Left
+#define XK_KP_Left 0xFF96
+#endif
+#ifndef XK_KP_Up
+#define XK_KP_Up 0xFF97
+#endif
+#ifndef XK_KP_Right
+#define XK_KP_Right 0xFF98
+#endif
+#ifndef XK_KP_Down
+#define XK_KP_Down 0xFF99
+#endif
+#ifndef XK_KP_Prior
+#define XK_KP_Prior 0xFF9A
+#endif
+#ifndef XK_KP_Next
+#define XK_KP_Next 0xFF9B
+#endif
+#ifndef XK_KP_End
+#define XK_KP_End 0xFF9C
+#endif
+#ifndef XK_KP_Insert
+#define XK_KP_Insert 0xFF9E
+#endif
+#ifndef XK_KP_Delete
+#define XK_KP_Delete 0xFF9F
+#endif
+
+// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
+// multimedia keys. They are included here as not every system has them.
+#define XF86XK_MonBrightnessUp 0x1008FF02
+#define XF86XK_MonBrightnessDown 0x1008FF03
+#define XF86XK_KbdLightOnOff 0x1008FF04
+#define XF86XK_KbdBrightnessUp 0x1008FF05
+#define XF86XK_KbdBrightnessDown 0x1008FF06
+#define XF86XK_Standby 0x1008FF10
+#define XF86XK_AudioLowerVolume 0x1008FF11
+#define XF86XK_AudioMute 0x1008FF12
+#define XF86XK_AudioRaiseVolume 0x1008FF13
+#define XF86XK_AudioPlay 0x1008FF14
+#define XF86XK_AudioStop 0x1008FF15
+#define XF86XK_AudioPrev 0x1008FF16
+#define XF86XK_AudioNext 0x1008FF17
+#define XF86XK_HomePage 0x1008FF18
+#define XF86XK_Mail 0x1008FF19
+#define XF86XK_Start 0x1008FF1A
+#define XF86XK_Search 0x1008FF1B
+#define XF86XK_AudioRecord 0x1008FF1C
+#define XF86XK_Calculator 0x1008FF1D
+#define XF86XK_Memo 0x1008FF1E
+#define XF86XK_ToDoList 0x1008FF1F
+#define XF86XK_Calendar 0x1008FF20
+#define XF86XK_PowerDown 0x1008FF21
+#define XF86XK_ContrastAdjust 0x1008FF22
+#define XF86XK_Back 0x1008FF26
+#define XF86XK_Forward 0x1008FF27
+#define XF86XK_Stop 0x1008FF28
+#define XF86XK_Refresh 0x1008FF29
+#define XF86XK_PowerOff 0x1008FF2A
+#define XF86XK_WakeUp 0x1008FF2B
+#define XF86XK_Eject 0x1008FF2C
+#define XF86XK_ScreenSaver 0x1008FF2D
+#define XF86XK_WWW 0x1008FF2E
+#define XF86XK_Sleep 0x1008FF2F
+#define XF86XK_Favorites 0x1008FF30
+#define XF86XK_AudioPause 0x1008FF31
+#define XF86XK_AudioMedia 0x1008FF32
+#define XF86XK_MyComputer 0x1008FF33
+#define XF86XK_LightBulb 0x1008FF35
+#define XF86XK_Shop 0x1008FF36
+#define XF86XK_History 0x1008FF37
+#define XF86XK_OpenURL 0x1008FF38
+#define XF86XK_AddFavorite 0x1008FF39
+#define XF86XK_HotLinks 0x1008FF3A
+#define XF86XK_BrightnessAdjust 0x1008FF3B
+#define XF86XK_Finance 0x1008FF3C
+#define XF86XK_Community 0x1008FF3D
+#define XF86XK_AudioRewind 0x1008FF3E
+#define XF86XK_BackForward 0x1008FF3F
+#define XF86XK_Launch0 0x1008FF40
+#define XF86XK_Launch1 0x1008FF41
+#define XF86XK_Launch2 0x1008FF42
+#define XF86XK_Launch3 0x1008FF43
+#define XF86XK_Launch4 0x1008FF44
+#define XF86XK_Launch5 0x1008FF45
+#define XF86XK_Launch6 0x1008FF46
+#define XF86XK_Launch7 0x1008FF47
+#define XF86XK_Launch8 0x1008FF48
+#define XF86XK_Launch9 0x1008FF49
+#define XF86XK_LaunchA 0x1008FF4A
+#define XF86XK_LaunchB 0x1008FF4B
+#define XF86XK_LaunchC 0x1008FF4C
+#define XF86XK_LaunchD 0x1008FF4D
+#define XF86XK_LaunchE 0x1008FF4E
+#define XF86XK_LaunchF 0x1008FF4F
+#define XF86XK_ApplicationLeft 0x1008FF50
+#define XF86XK_ApplicationRight 0x1008FF51
+#define XF86XK_Book 0x1008FF52
+#define XF86XK_CD 0x1008FF53
+#define XF86XK_Calculater 0x1008FF54
+#define XF86XK_Clear 0x1008FF55
+#define XF86XK_ClearGrab 0x1008FE21
+#define XF86XK_Close 0x1008FF56
+#define XF86XK_Copy 0x1008FF57
+#define XF86XK_Cut 0x1008FF58
+#define XF86XK_Display 0x1008FF59
+#define XF86XK_DOS 0x1008FF5A
+#define XF86XK_Documents 0x1008FF5B
+#define XF86XK_Excel 0x1008FF5C
+#define XF86XK_Explorer 0x1008FF5D
+#define XF86XK_Game 0x1008FF5E
+#define XF86XK_Go 0x1008FF5F
+#define XF86XK_iTouch 0x1008FF60
+#define XF86XK_LogOff 0x1008FF61
+#define XF86XK_Market 0x1008FF62
+#define XF86XK_Meeting 0x1008FF63
+#define XF86XK_MenuKB 0x1008FF65
+#define XF86XK_MenuPB 0x1008FF66
+#define XF86XK_MySites 0x1008FF67
+#define XF86XK_News 0x1008FF69
+#define XF86XK_OfficeHome 0x1008FF6A
+#define XF86XK_Option 0x1008FF6C
+#define XF86XK_Paste 0x1008FF6D
+#define XF86XK_Phone 0x1008FF6E
+#define XF86XK_Reply 0x1008FF72
+#define XF86XK_Reload 0x1008FF73
+#define XF86XK_RotateWindows 0x1008FF74
+#define XF86XK_RotationPB 0x1008FF75
+#define XF86XK_RotationKB 0x1008FF76
+#define XF86XK_Save 0x1008FF77
+#define XF86XK_Send 0x1008FF7B
+#define XF86XK_Spell 0x1008FF7C
+#define XF86XK_SplitScreen 0x1008FF7D
+#define XF86XK_Support 0x1008FF7E
+#define XF86XK_TaskPane 0x1008FF7F
+#define XF86XK_Terminal 0x1008FF80
+#define XF86XK_Tools 0x1008FF81
+#define XF86XK_Travel 0x1008FF82
+#define XF86XK_Video 0x1008FF87
+#define XF86XK_Word 0x1008FF89
+#define XF86XK_Xfer 0x1008FF8A
+#define XF86XK_ZoomIn 0x1008FF8B
+#define XF86XK_ZoomOut 0x1008FF8C
+#define XF86XK_Away 0x1008FF8D
+#define XF86XK_Messenger 0x1008FF8E
+#define XF86XK_WebCam 0x1008FF8F
+#define XF86XK_MailForward 0x1008FF90
+#define XF86XK_Pictures 0x1008FF91
+#define XF86XK_Music 0x1008FF92
+#define XF86XK_Battery 0x1008FF93
+#define XF86XK_Bluetooth 0x1008FF94
+#define XF86XK_WLAN 0x1008FF95
+#define XF86XK_UWB 0x1008FF96
+#define XF86XK_AudioForward 0x1008FF97
+#define XF86XK_AudioRepeat 0x1008FF98
+#define XF86XK_AudioRandomPlay 0x1008FF99
+#define XF86XK_Subtitle 0x1008FF9A
+#define XF86XK_AudioCycleTrack 0x1008FF9B
+#define XF86XK_Time 0x1008FF9F
+#define XF86XK_Select 0x1008FFA0
+#define XF86XK_View 0x1008FFA1
+#define XF86XK_TopMenu 0x1008FFA2
+#define XF86XK_Suspend 0x1008FFA7
+#define XF86XK_Hibernate 0x1008FFA8
+
+
+// end of XF86keysyms.h
+
+// Special keys used by Qtopia, mapped into the X11 private keypad range.
+#define QTOPIAXK_Select 0x11000601
+#define QTOPIAXK_Yes 0x11000602
+#define QTOPIAXK_No 0x11000603
+#define QTOPIAXK_Cancel 0x11000604
+#define QTOPIAXK_Printer 0x11000605
+#define QTOPIAXK_Execute 0x11000606
+#define QTOPIAXK_Sleep 0x11000607
+#define QTOPIAXK_Play 0x11000608
+#define QTOPIAXK_Zoom 0x11000609
+#define QTOPIAXK_Context1 0x1100060A
+#define QTOPIAXK_Context2 0x1100060B
+#define QTOPIAXK_Context3 0x1100060C
+#define QTOPIAXK_Context4 0x1100060D
+#define QTOPIAXK_Call 0x1100060E
+#define QTOPIAXK_Hangup 0x1100060F
+#define QTOPIAXK_Flip 0x11000610
+
+// keyboard mapping table
+static const unsigned int KeyTbl[] = {
+
+ // misc keys
+
+ XK_Escape, Qt::Key_Escape,
+ XK_Tab, Qt::Key_Tab,
+ XK_ISO_Left_Tab, Qt::Key_Backtab,
+ XK_BackSpace, Qt::Key_Backspace,
+ XK_Return, Qt::Key_Return,
+ XK_Insert, Qt::Key_Insert,
+ XK_Delete, Qt::Key_Delete,
+ XK_Clear, Qt::Key_Delete,
+ XK_Pause, Qt::Key_Pause,
+ XK_Print, Qt::Key_Print,
+ 0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq
+ 0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq
+
+ // cursor movement
+
+ XK_Home, Qt::Key_Home,
+ XK_End, Qt::Key_End,
+ XK_Left, Qt::Key_Left,
+ XK_Up, Qt::Key_Up,
+ XK_Right, Qt::Key_Right,
+ XK_Down, Qt::Key_Down,
+ XK_Prior, Qt::Key_PageUp,
+ XK_Next, Qt::Key_PageDown,
+
+ // modifiers
+
+ XK_Shift_L, Qt::Key_Shift,
+ XK_Shift_R, Qt::Key_Shift,
+ XK_Shift_Lock, Qt::Key_Shift,
+ XK_Control_L, Qt::Key_Control,
+ XK_Control_R, Qt::Key_Control,
+ XK_Meta_L, Qt::Key_Meta,
+ XK_Meta_R, Qt::Key_Meta,
+ XK_Alt_L, Qt::Key_Alt,
+ XK_Alt_R, Qt::Key_Alt,
+ XK_Caps_Lock, Qt::Key_CapsLock,
+ XK_Num_Lock, Qt::Key_NumLock,
+ XK_Scroll_Lock, Qt::Key_ScrollLock,
+ XK_Super_L, Qt::Key_Super_L,
+ XK_Super_R, Qt::Key_Super_R,
+ XK_Menu, Qt::Key_Menu,
+ XK_Hyper_L, Qt::Key_Hyper_L,
+ XK_Hyper_R, Qt::Key_Hyper_R,
+ XK_Help, Qt::Key_Help,
+ 0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab
+ 0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11)
+ 0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12)
+
+ // numeric and function keypad keys
+
+ XK_KP_Space, Qt::Key_Space,
+ XK_KP_Tab, Qt::Key_Tab,
+ XK_KP_Enter, Qt::Key_Enter,
+ //XK_KP_F1, Qt::Key_F1,
+ //XK_KP_F2, Qt::Key_F2,
+ //XK_KP_F3, Qt::Key_F3,
+ //XK_KP_F4, Qt::Key_F4,
+ XK_KP_Home, Qt::Key_Home,
+ XK_KP_Left, Qt::Key_Left,
+ XK_KP_Up, Qt::Key_Up,
+ XK_KP_Right, Qt::Key_Right,
+ XK_KP_Down, Qt::Key_Down,
+ XK_KP_Prior, Qt::Key_PageUp,
+ XK_KP_Next, Qt::Key_PageDown,
+ XK_KP_End, Qt::Key_End,
+ XK_KP_Begin, Qt::Key_Clear,
+ XK_KP_Insert, Qt::Key_Insert,
+ XK_KP_Delete, Qt::Key_Delete,
+ XK_KP_Equal, Qt::Key_Equal,
+ XK_KP_Multiply, Qt::Key_Asterisk,
+ XK_KP_Add, Qt::Key_Plus,
+ XK_KP_Separator, Qt::Key_Comma,
+ XK_KP_Subtract, Qt::Key_Minus,
+ XK_KP_Decimal, Qt::Key_Period,
+ XK_KP_Divide, Qt::Key_Slash,
+
+ // International input method support keys
+
+ // International & multi-key character composition
+ XK_ISO_Level3_Shift, Qt::Key_AltGr,
+ XK_Multi_key, Qt::Key_Multi_key,
+ XK_Codeinput, Qt::Key_Codeinput,
+ XK_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_MultipleCandidate, Qt::Key_MultipleCandidate,
+ XK_PreviousCandidate, Qt::Key_PreviousCandidate,
+
+ // Misc Functions
+ XK_Mode_switch, Qt::Key_Mode_switch,
+ XK_script_switch, Qt::Key_Mode_switch,
+
+ // Japanese keyboard support
+ XK_Kanji, Qt::Key_Kanji,
+ XK_Muhenkan, Qt::Key_Muhenkan,
+ //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
+ XK_Henkan_Mode, Qt::Key_Henkan,
+ XK_Henkan, Qt::Key_Henkan,
+ XK_Romaji, Qt::Key_Romaji,
+ XK_Hiragana, Qt::Key_Hiragana,
+ XK_Katakana, Qt::Key_Katakana,
+ XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
+ XK_Zenkaku, Qt::Key_Zenkaku,
+ XK_Hankaku, Qt::Key_Hankaku,
+ XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
+ XK_Touroku, Qt::Key_Touroku,
+ XK_Massyo, Qt::Key_Massyo,
+ XK_Kana_Lock, Qt::Key_Kana_Lock,
+ XK_Kana_Shift, Qt::Key_Kana_Shift,
+ XK_Eisu_Shift, Qt::Key_Eisu_Shift,
+ XK_Eisu_toggle, Qt::Key_Eisu_toggle,
+ //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
+ //XK_Zen_Koho, Qt::Key_Zen_Koho,
+ //XK_Mae_Koho, Qt::Key_Mae_Koho,
+ XK_Kanji_Bangou, Qt::Key_Codeinput,
+ XK_Zen_Koho, Qt::Key_MultipleCandidate,
+ XK_Mae_Koho, Qt::Key_PreviousCandidate,
+
+#ifdef XK_KOREAN
+ // Korean keyboard support
+ XK_Hangul, Qt::Key_Hangul,
+ XK_Hangul_Start, Qt::Key_Hangul_Start,
+ XK_Hangul_End, Qt::Key_Hangul_End,
+ XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
+ XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
+ XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
+ //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
+ XK_Hangul_Codeinput, Qt::Key_Codeinput,
+ XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
+ XK_Hangul_Banja, Qt::Key_Hangul_Banja,
+ XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
+ XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
+ //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
+ //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
+ //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
+ XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
+ XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
+ XK_Hangul_Special, Qt::Key_Hangul_Special,
+ //XK_Hangul_switch, Qt::Key_Hangul_switch,
+ XK_Hangul_switch, Qt::Key_Mode_switch,
+#endif // XK_KOREAN
+
+ // dead keys
+ XK_dead_grave, Qt::Key_Dead_Grave,
+ XK_dead_acute, Qt::Key_Dead_Acute,
+ XK_dead_circumflex, Qt::Key_Dead_Circumflex,
+ XK_dead_tilde, Qt::Key_Dead_Tilde,
+ XK_dead_macron, Qt::Key_Dead_Macron,
+ XK_dead_breve, Qt::Key_Dead_Breve,
+ XK_dead_abovedot, Qt::Key_Dead_Abovedot,
+ XK_dead_diaeresis, Qt::Key_Dead_Diaeresis,
+ XK_dead_abovering, Qt::Key_Dead_Abovering,
+ XK_dead_doubleacute, Qt::Key_Dead_Doubleacute,
+ XK_dead_caron, Qt::Key_Dead_Caron,
+ XK_dead_cedilla, Qt::Key_Dead_Cedilla,
+ XK_dead_ogonek, Qt::Key_Dead_Ogonek,
+ XK_dead_iota, Qt::Key_Dead_Iota,
+ XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
+ XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
+ XK_dead_belowdot, Qt::Key_Dead_Belowdot,
+ XK_dead_hook, Qt::Key_Dead_Hook,
+ XK_dead_horn, Qt::Key_Dead_Horn,
+
+ // Special keys from X.org - This include multimedia keys,
+ // wireless/bluetooth/uwb keys, special launcher keys, etc.
+ XF86XK_Back, Qt::Key_Back,
+ XF86XK_Forward, Qt::Key_Forward,
+ XF86XK_Stop, Qt::Key_Stop,
+ XF86XK_Refresh, Qt::Key_Refresh,
+ XF86XK_Favorites, Qt::Key_Favorites,
+ XF86XK_AudioMedia, Qt::Key_LaunchMedia,
+ XF86XK_OpenURL, Qt::Key_OpenUrl,
+ XF86XK_HomePage, Qt::Key_HomePage,
+ XF86XK_Search, Qt::Key_Search,
+ XF86XK_AudioLowerVolume, Qt::Key_VolumeDown,
+ XF86XK_AudioMute, Qt::Key_VolumeMute,
+ XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp,
+ XF86XK_AudioPlay, Qt::Key_MediaPlay,
+ XF86XK_AudioStop, Qt::Key_MediaStop,
+ XF86XK_AudioPrev, Qt::Key_MediaPrevious,
+ XF86XK_AudioNext, Qt::Key_MediaNext,
+ XF86XK_AudioRecord, Qt::Key_MediaRecord,
+ XF86XK_Mail, Qt::Key_LaunchMail,
+ XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 5: remap properly
+ XF86XK_Calculator, Qt::Key_Launch1,
+ XF86XK_Memo, Qt::Key_Memo,
+ XF86XK_ToDoList, Qt::Key_ToDoList,
+ XF86XK_Calendar, Qt::Key_Calendar,
+ XF86XK_PowerDown, Qt::Key_PowerDown,
+ XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust,
+ XF86XK_Standby, Qt::Key_Standby,
+ XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp,
+ XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown,
+ XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff,
+ XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp,
+ XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown,
+ XF86XK_PowerOff, Qt::Key_PowerOff,
+ XF86XK_WakeUp, Qt::Key_WakeUp,
+ XF86XK_Eject, Qt::Key_Eject,
+ XF86XK_ScreenSaver, Qt::Key_ScreenSaver,
+ XF86XK_WWW, Qt::Key_WWW,
+ XF86XK_Sleep, Qt::Key_Sleep,
+ XF86XK_LightBulb, Qt::Key_LightBulb,
+ XF86XK_Shop, Qt::Key_Shop,
+ XF86XK_History, Qt::Key_History,
+ XF86XK_AddFavorite, Qt::Key_AddFavorite,
+ XF86XK_HotLinks, Qt::Key_HotLinks,
+ XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust,
+ XF86XK_Finance, Qt::Key_Finance,
+ XF86XK_Community, Qt::Key_Community,
+ XF86XK_AudioRewind, Qt::Key_AudioRewind,
+ XF86XK_BackForward, Qt::Key_BackForward,
+ XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft,
+ XF86XK_ApplicationRight, Qt::Key_ApplicationRight,
+ XF86XK_Book, Qt::Key_Book,
+ XF86XK_CD, Qt::Key_CD,
+ XF86XK_Calculater, Qt::Key_Calculator,
+ XF86XK_Clear, Qt::Key_Clear,
+ XF86XK_ClearGrab, Qt::Key_ClearGrab,
+ XF86XK_Close, Qt::Key_Close,
+ XF86XK_Copy, Qt::Key_Copy,
+ XF86XK_Cut, Qt::Key_Cut,
+ XF86XK_Display, Qt::Key_Display,
+ XF86XK_DOS, Qt::Key_DOS,
+ XF86XK_Documents, Qt::Key_Documents,
+ XF86XK_Excel, Qt::Key_Excel,
+ XF86XK_Explorer, Qt::Key_Explorer,
+ XF86XK_Game, Qt::Key_Game,
+ XF86XK_Go, Qt::Key_Go,
+ XF86XK_iTouch, Qt::Key_iTouch,
+ XF86XK_LogOff, Qt::Key_LogOff,
+ XF86XK_Market, Qt::Key_Market,
+ XF86XK_Meeting, Qt::Key_Meeting,
+ XF86XK_MenuKB, Qt::Key_MenuKB,
+ XF86XK_MenuPB, Qt::Key_MenuPB,
+ XF86XK_MySites, Qt::Key_MySites,
+ XF86XK_News, Qt::Key_News,
+ XF86XK_OfficeHome, Qt::Key_OfficeHome,
+ XF86XK_Option, Qt::Key_Option,
+ XF86XK_Paste, Qt::Key_Paste,
+ XF86XK_Phone, Qt::Key_Phone,
+ XF86XK_Reply, Qt::Key_Reply,
+ XF86XK_Reload, Qt::Key_Reload,
+ XF86XK_RotateWindows, Qt::Key_RotateWindows,
+ XF86XK_RotationPB, Qt::Key_RotationPB,
+ XF86XK_RotationKB, Qt::Key_RotationKB,
+ XF86XK_Save, Qt::Key_Save,
+ XF86XK_Send, Qt::Key_Send,
+ XF86XK_Spell, Qt::Key_Spell,
+ XF86XK_SplitScreen, Qt::Key_SplitScreen,
+ XF86XK_Support, Qt::Key_Support,
+ XF86XK_TaskPane, Qt::Key_TaskPane,
+ XF86XK_Terminal, Qt::Key_Terminal,
+ XF86XK_Tools, Qt::Key_Tools,
+ XF86XK_Travel, Qt::Key_Travel,
+ XF86XK_Video, Qt::Key_Video,
+ XF86XK_Word, Qt::Key_Word,
+ XF86XK_Xfer, Qt::Key_Xfer,
+ XF86XK_ZoomIn, Qt::Key_ZoomIn,
+ XF86XK_ZoomOut, Qt::Key_ZoomOut,
+ XF86XK_Away, Qt::Key_Away,
+ XF86XK_Messenger, Qt::Key_Messenger,
+ XF86XK_WebCam, Qt::Key_WebCam,
+ XF86XK_MailForward, Qt::Key_MailForward,
+ XF86XK_Pictures, Qt::Key_Pictures,
+ XF86XK_Music, Qt::Key_Music,
+ XF86XK_Battery, Qt::Key_Battery,
+ XF86XK_Bluetooth, Qt::Key_Bluetooth,
+ XF86XK_WLAN, Qt::Key_WLAN,
+ XF86XK_UWB, Qt::Key_UWB,
+ XF86XK_AudioForward, Qt::Key_AudioForward,
+ XF86XK_AudioRepeat, Qt::Key_AudioRepeat,
+ XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay,
+ XF86XK_Subtitle, Qt::Key_Subtitle,
+ XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack,
+ XF86XK_Time, Qt::Key_Time,
+ XF86XK_Select, Qt::Key_Select,
+ XF86XK_View, Qt::Key_View,
+ XF86XK_TopMenu, Qt::Key_TopMenu,
+ XF86XK_Bluetooth, Qt::Key_Bluetooth,
+ XF86XK_Suspend, Qt::Key_Suspend,
+ XF86XK_Hibernate, Qt::Key_Hibernate,
+ XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly
+ XF86XK_Launch1, Qt::Key_Launch3,
+ XF86XK_Launch2, Qt::Key_Launch4,
+ XF86XK_Launch3, Qt::Key_Launch5,
+ XF86XK_Launch4, Qt::Key_Launch6,
+ XF86XK_Launch5, Qt::Key_Launch7,
+ XF86XK_Launch6, Qt::Key_Launch8,
+ XF86XK_Launch7, Qt::Key_Launch9,
+ XF86XK_Launch8, Qt::Key_LaunchA,
+ XF86XK_Launch9, Qt::Key_LaunchB,
+ XF86XK_LaunchA, Qt::Key_LaunchC,
+ XF86XK_LaunchB, Qt::Key_LaunchD,
+ XF86XK_LaunchC, Qt::Key_LaunchE,
+ XF86XK_LaunchD, Qt::Key_LaunchF,
+ XF86XK_LaunchE, Qt::Key_LaunchG,
+ XF86XK_LaunchF, Qt::Key_LaunchH,
+
+ // Qtopia keys
+ QTOPIAXK_Select, Qt::Key_Select,
+ QTOPIAXK_Yes, Qt::Key_Yes,
+ QTOPIAXK_No, Qt::Key_No,
+ QTOPIAXK_Cancel, Qt::Key_Cancel,
+ QTOPIAXK_Printer, Qt::Key_Printer,
+ QTOPIAXK_Execute, Qt::Key_Execute,
+ QTOPIAXK_Sleep, Qt::Key_Sleep,
+ QTOPIAXK_Play, Qt::Key_Play,
+ QTOPIAXK_Zoom, Qt::Key_Zoom,
+ QTOPIAXK_Context1, Qt::Key_Context1,
+ QTOPIAXK_Context2, Qt::Key_Context2,
+ QTOPIAXK_Context3, Qt::Key_Context3,
+ QTOPIAXK_Context4, Qt::Key_Context4,
+ QTOPIAXK_Call, Qt::Key_Call,
+ QTOPIAXK_Hangup, Qt::Key_Hangup,
+ QTOPIAXK_Flip, Qt::Key_Flip,
+
+ 0, 0
+};
+
+static const unsigned short katakanaKeysymsToUnicode[] = {
+ 0x0000, 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1,
+ 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3,
+ 0x30FC, 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD,
+ 0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD,
+ 0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC,
+ 0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE,
+ 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9,
+ 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C
+};
+
+static const unsigned short cyrillicKeysymsToUnicode[] = {
+ 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f,
+ 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f,
+ 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
+ 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
+ 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a
+};
+
+static const unsigned short greekKeysymsToUnicode[] = {
+ 0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c,
+ 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015,
+ 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc,
+ 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+ 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
+ 0x03c8, 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short technicalKeysymsToUnicode[] = {
+ 0x0000, 0x23B7, 0x250C, 0x2500, 0x2320, 0x2321, 0x2502, 0x23A1,
+ 0x23A3, 0x23A4, 0x23A6, 0x239B, 0x239D, 0x239E, 0x23A0, 0x23A8,
+ 0x23AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222B,
+ 0x2234, 0x221D, 0x221E, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000,
+ 0x223C, 0x2243, 0x0000, 0x0000, 0x0000, 0x21D4, 0x21D2, 0x2261,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221A, 0x0000,
+ 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222A, 0x2227, 0x2228,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193, 0x0000
+};
+
+static const unsigned short specialKeysymsToUnicode[] = {
+ 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x0000, 0x0000,
+ 0x2424, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
+ 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C,
+ 0x2502, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short publishingKeysymsToUnicode[] = {
+ 0x0000, 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009,
+ 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025,
+ 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a,
+ 0x2105, 0x0000, 0x0000, 0x2012, 0x2329, 0x0000, 0x232a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000,
+ 0x0000, 0x2122, 0x2613, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25af,
+ 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033,
+ 0x0000, 0x271d, 0x0000, 0x25ac, 0x25c0, 0x25b6, 0x25cf, 0x25ae,
+ 0x25e6, 0x25ab, 0x25ad, 0x25b3, 0x25bd, 0x2606, 0x2022, 0x25aa,
+ 0x25b2, 0x25bc, 0x261c, 0x261e, 0x2663, 0x2666, 0x2665, 0x0000,
+ 0x2720, 0x2020, 0x2021, 0x2713, 0x2717, 0x266f, 0x266d, 0x2642,
+ 0x2640, 0x260e, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e, 0x0000
+};
+
+static const unsigned short aplKeysymsToUnicode[] = {
+ 0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003e, 0x0000,
+ 0x2228, 0x2227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00af, 0x0000, 0x22a5, 0x2229, 0x230a, 0x0000, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x2218, 0x0000, 0x2395, 0x0000, 0x22a4, 0x25cb,
+ 0x0000, 0x0000, 0x0000, 0x2308, 0x0000, 0x0000, 0x222a, 0x0000,
+ 0x2283, 0x0000, 0x2282, 0x0000, 0x22a2, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x22a3, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short koreanKeysymsToUnicode[] = {
+ 0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
+ 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
+ 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147,
+ 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f,
+ 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157,
+ 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f,
+ 0x3160, 0x3161, 0x3162, 0x3163, 0x11a8, 0x11a9, 0x11aa, 0x11ab,
+ 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3,
+ 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb,
+ 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x316d,
+ 0x3171, 0x3178, 0x317f, 0x3181, 0x3184, 0x3186, 0x318d, 0x318e,
+ 0x11eb, 0x11f0, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9
+};
+
+static QChar keysymToUnicode(unsigned char byte3, unsigned char byte4)
+{
+ switch (byte3) {
+ case 0x04:
+ // katakana
+ if (byte4 > 0xa0 && byte4 < 0xe0)
+ return QChar(katakanaKeysymsToUnicode[byte4 - 0xa0]);
+ else if (byte4 == 0x7e)
+ return QChar(0x203e); // Overline
+ break;
+ case 0x06:
+ // russian, use lookup table
+ if (byte4 > 0xa0)
+ return QChar(cyrillicKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x07:
+ // greek
+ if (byte4 > 0xa0)
+ return QChar(greekKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x08:
+ // technical
+ if (byte4 > 0xa0)
+ return QChar(technicalKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x09:
+ // special
+ if (byte4 >= 0xe0)
+ return QChar(specialKeysymsToUnicode[byte4 - 0xe0]);
+ break;
+ case 0x0a:
+ // publishing
+ if (byte4 > 0xa0)
+ return QChar(publishingKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x0b:
+ // APL
+ if (byte4 > 0xa0)
+ return QChar(aplKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ case 0x0e:
+ // Korean
+ if (byte4 > 0xa0)
+ return QChar(koreanKeysymsToUnicode[byte4 - 0xa0]);
+ break;
+ default:
+ break;
+ }
+ return QChar(0x0);
+}
+
+Qt::KeyboardModifiers QXlibKeyboard::translateModifiers(int s)
+{
+ Qt::KeyboardModifiers ret = 0;
+ if (s & ShiftMask)
+ ret |= Qt::ShiftModifier;
+ if (s & ControlMask)
+ ret |= Qt::ControlModifier;
+ if (s & m_alt_mask)
+ ret |= Qt::AltModifier;
+ if (s & m_meta_mask)
+ ret |= Qt::MetaModifier;
+// if (s & m_mode_switch_mask) //doesn't seem to work correctly
+// ret |= Qt::GroupSwitchModifier;
+ return ret;
+}
+
+void QXlibKeyboard::setMask(KeySym sym, uint mask)
+{
+ 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;
+ }
+}
+
+int QXlibKeyboard::translateKeySym(uint key) const
+{
+ int code = -1;
+ int i = 0; // any other keys
+ while (KeyTbl[i]) {
+ if (key == KeyTbl[i]) {
+ code = (int)KeyTbl[i+1];
+ break;
+ }
+ i += 2;
+ }
+ if (m_meta_mask) {
+ // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
+ if (m_meta_mask == m_super_mask && (code == Qt::Key_Super_L || code == Qt::Key_Super_R)) {
+ code = Qt::Key_Meta;
+ } else if (m_meta_mask == m_hyper_mask && (code == Qt::Key_Hyper_L || code == Qt::Key_Hyper_R)) {
+ code = Qt::Key_Meta;
+ }
+ }
+ return code;
+}
+
+QString QXlibKeyboard::translateKeySym(KeySym keysym, uint xmodifiers,
+ int &code, Qt::KeyboardModifiers &modifiers,
+ QByteArray &chars, int &count)
+{
+ // all keysyms smaller than 0xff00 are actally keys that can be mapped to unicode chars
+
+ QTextCodec *mapper = QTextCodec::codecForLocale();
+ QChar converted;
+
+ if (/*count == 0 &&*/ keysym < 0xff00) {
+ unsigned char byte3 = (unsigned char)(keysym >> 8);
+ int mib = -1;
+ switch(byte3) {
+ case 0: // Latin 1
+ case 1: // Latin 2
+ case 2: //latin 3
+ case 3: // latin4
+ mib = byte3 + 4; break;
+ case 5: // arabic
+ mib = 82; break;
+ case 12: // Hebrew
+ mib = 85; break;
+ case 13: // Thai
+ mib = 2259; break;
+ case 4: // kana
+ case 6: // cyrillic
+ case 7: // greek
+ case 8: // technical, no mapping here at the moment
+ case 9: // Special
+ case 10: // Publishing
+ case 11: // APL
+ case 14: // Korean, no mapping
+ mib = -1; // manual conversion
+ mapper= 0;
+#if !defined(QT_NO_XIM)
+ converted = keysymToUnicode(byte3, keysym & 0xff);
+#endif
+ case 0x20:
+ // currency symbols
+ if (keysym >= 0x20a0 && keysym <= 0x20ac) {
+ mib = -1; // manual conversion
+ mapper = 0;
+ converted = (uint)keysym;
+ }
+ break;
+ default:
+ break;
+ }
+ if (mib != -1) {
+ mapper = QTextCodec::codecForMib(mib);
+ if (chars.isEmpty())
+ chars.resize(1);
+ chars[0] = (unsigned char) (keysym & 0xff); // get only the fourth bit for conversion later
+ count = 1;
+ }
+ } else if (keysym >= 0x1000000 && keysym <= 0x100ffff) {
+ converted = (ushort) (keysym - 0x1000000);
+ mapper = 0;
+ }
+ if (count < (int)chars.size()-1)
+ chars[count] = '\0';
+
+ QString text;
+ if (!mapper && converted.unicode() != 0x0) {
+ text = converted;
+ } else if (!chars.isEmpty()) {
+ // convert chars (8bit) to text (unicode).
+ if (mapper)
+ text = mapper->toUnicode(chars.data(), count, 0);
+ if (text.isEmpty()) {
+ // no mapper, or codec couldn't convert to unicode (this
+ // can happen when running in the C locale or with no LANG
+ // set). try converting from latin-1
+ text = QString::fromLatin1(chars);
+ }
+ }
+
+ modifiers = translateModifiers(xmodifiers);
+
+ // Commentary in X11/keysymdef says that X codes match ASCII, so it
+ // is safe to use the locale functions to process X codes in ISO8859-1.
+ //
+ // This is mainly for compatibility - applications should not use the
+ // Qt keycodes between 128 and 255, but should rather use the
+ // QKeyEvent::text().
+ //
+ if (keysym < 128 || (keysym < 256 && (!mapper || mapper->mibEnum()==4))) {
+ // upper-case key, if known
+ code = isprint((int)keysym) ? toupper((int)keysym) : 0;
+ } else if (keysym >= XK_F1 && keysym <= XK_F35) {
+ // function keys
+ code = Qt::Key_F1 + ((int)keysym - XK_F1);
+ } else if (keysym >= XK_KP_Space && keysym <= XK_KP_9) {
+ if (keysym >= XK_KP_0) {
+ // numeric keypad keys
+ code = Qt::Key_0 + ((int)keysym - XK_KP_0);
+ } else {
+ code = translateKeySym(keysym);
+ }
+ modifiers |= Qt::KeypadModifier;
+ } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f && text.unicode()->unicode() != 0x7f && !(keysym >= XK_dead_grave && keysym <= XK_dead_horn)) {
+ code = text.unicode()->toUpper().unicode();
+ } else {
+ // any other keys
+ code = translateKeySym(keysym);
+
+ if (code == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) {
+ // map shift+tab to shift+backtab, QShortcutMap knows about it
+ // and will handle it.
+ code = Qt::Key_Backtab;
+ text = QString();
+ }
+ }
+
+ return text;
+}
+
+QXlibKeyboard::QXlibKeyboard(QXlibScreen *screen)
+ : m_screen(screen)
+ , m_alt_mask(0)
+ , m_super_mask(0)
+ , m_hyper_mask(0)
+ , m_meta_mask(0)
+{
+ changeLayout();
+}
+
+void QXlibKeyboard::changeLayout()
+{
+ XkbDescPtr xkbDesc = XkbGetMap(m_screen->display()->nativeDisplay(), XkbAllClientInfoMask, XkbUseCoreKbd);
+ for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) {
+ const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0;
+ if (mask == 0) {
+ // key is not bound to a modifier
+ continue;
+ }
+
+ for (int j = 0; j < XkbKeyGroupsWidth(xkbDesc, i); ++j) {
+ KeySym keySym = XkbKeySym(xkbDesc, i, j);
+ if (keySym == NoSymbol)
+ continue;
+ setMask(keySym, mask);
+ }
+ }
+ XkbFreeKeyboard(xkbDesc, XkbAllComponentsMask, true);
+
+}
+
+static Qt::KeyboardModifiers modifierFromKeyCode(int qtcode)
+{
+ switch (qtcode) {
+ case Qt::Key_Control:
+ return Qt::ControlModifier;
+ case Qt::Key_Alt:
+ return Qt::AltModifier;
+ case Qt::Key_Shift:
+ return Qt::ShiftModifier;
+ case Qt::Key_Meta:
+ return Qt::MetaModifier;
+ default:
+ return Qt::NoModifier;
+ }
+}
+
+void QXlibKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, XKeyEvent *ev)
+{
+ int qtcode = 0;
+ Qt::KeyboardModifiers modifiers = translateModifiers(ev->state);
+ QByteArray chars;
+ chars.resize(513);
+ int count = 0;
+ KeySym keySym;
+ count = XLookupString(ev,chars.data(),chars.size(),&keySym,0);
+ QString text = translateKeySym(keySym,ev->state,qtcode,modifiers,chars,count);
+ QWindowSystemInterface::handleExtendedKeyEvent(widget,ev->time,type,qtcode,modifiers,ev->keycode,0,ev->state,text.left(count));
+}
diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.h b/src/plugins/platforms/xlib/qxlibkeyboard.h
new file mode 100644
index 0000000000..5e0135afa6
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibkeyboard.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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 QTESTLITEKEYBOARD_H
+#define QTESTLITEKEYBOARD_H
+
+#include "qxlibintegration.h"
+
+class QXlibKeyboard
+{
+public:
+ QXlibKeyboard(QXlibScreen *screen);
+
+ void changeLayout();
+
+ void handleKeyEvent(QWidget *widget, QEvent::Type type, XKeyEvent *ev);
+
+ Qt::KeyboardModifiers translateModifiers(int s);
+
+private:
+
+ void setMask(KeySym sym, uint mask);
+ int translateKeySym(uint key) const;
+ QString translateKeySym(KeySym keysym, uint xmodifiers,
+ int &code, Qt::KeyboardModifiers &modifiers,
+ QByteArray &chars, int &count);
+
+ QXlibScreen *m_screen;
+
+ uint m_alt_mask;
+ uint m_super_mask;
+ uint m_hyper_mask;
+ uint m_meta_mask;
+ uint m_mode_switch_mask;
+ uint m_num_lock_mask;
+};
+
+#endif // QTESTLITEKEYBOARD_H
diff --git a/src/plugins/platforms/xlib/qxlibmime.cpp b/src/plugins/platforms/xlib/qxlibmime.cpp
new file mode 100644
index 0000000000..e98983d340
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibmime.cpp
@@ -0,0 +1,322 @@
+/****************************************************************************
+**
+** 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 "qxlibmime.h"
+
+#include "qxlibstatic.h"
+#include "qxlibscreen.h"
+
+#include <QtCore/QTextCodec>
+#include <QtGui/QImageWriter>
+#include <QtCore/QBuffer>
+
+QXlibMime::QXlibMime()
+ : QInternalMimeData()
+{ }
+
+QXlibMime::~QXlibMime()
+{}
+
+
+
+
+
+QString QXlibMime::mimeAtomToString(Display *display, Atom a)
+{
+ if (!a) return 0;
+
+ if (a == XA_STRING || a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)) {
+ return "text/plain"; // some Xdnd clients are dumb
+ }
+ char *atom = XGetAtomName(display, a);
+ QString result = QString::fromLatin1(atom);
+ XFree(atom);
+ return result;
+}
+
+Atom QXlibMime::mimeStringToAtom(Display *display, const QString &mimeType)
+{
+ if (mimeType.isEmpty())
+ return 0;
+ return XInternAtom(display, mimeType.toLatin1().constData(), False);
+}
+
+QStringList QXlibMime::mimeFormatsForAtom(Display *display, Atom a)
+{
+ QStringList formats;
+ if (a) {
+ QString atomName = mimeAtomToString(display, a);
+ formats.append(atomName);
+
+ // special cases for string type
+ if (a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)
+ || a == XA_STRING
+ || a == QXlibStatic::atom(QXlibStatic::TEXT)
+ || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT))
+ formats.append(QLatin1String("text/plain"));
+
+ // special cases for uris
+ if (atomName == QLatin1String("text/x-moz-url"))
+ formats.append(QLatin1String("text/uri-list"));
+
+ // special case for images
+ if (a == XA_PIXMAP)
+ formats.append(QLatin1String("image/ppm"));
+ }
+ return formats;
+}
+
+bool QXlibMime::mimeDataForAtom(Display *display, Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat)
+{
+ bool ret = false;
+ *atomFormat = a;
+ *dataFormat = 8;
+ QString atomName = mimeAtomToString(display, a);
+ if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
+ *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
+ if (atomName == QLatin1String("application/x-color"))
+ *dataFormat = 16;
+ ret = true;
+ } else {
+ if ((a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)
+ || a == XA_STRING
+ || a == QXlibStatic::atom(QXlibStatic::TEXT)
+ || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT))
+ && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
+ if (a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)){
+ *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
+ ret = true;
+ } else if (a == XA_STRING) {
+ *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
+ QLatin1String("text/plain"), mimeData)).toLocal8Bit();
+ ret = true;
+ } else if (a == QXlibStatic::atom(QXlibStatic::TEXT)
+ || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) {
+ // the ICCCM states that TEXT and COMPOUND_TEXT are in the
+ // encoding of choice, so we choose the encoding of the locale
+ QByteArray strData = QString::fromUtf8(QInternalMimeData::renderDataHelper(
+ QLatin1String("text/plain"), mimeData)).toLocal8Bit();
+ char *list[] = { strData.data(), NULL };
+
+ XICCEncodingStyle style = (a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT))
+ ? XCompoundTextStyle : XStdICCTextStyle;
+ XTextProperty textprop;
+ if (list[0] != NULL
+ && XmbTextListToTextProperty(display, list, 1, style,
+ &textprop) == Success) {
+ *atomFormat = textprop.encoding;
+ *dataFormat = textprop.format;
+ *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8);
+ ret = true;
+
+ XFree(textprop.value);
+ }
+ }
+ } 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 == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) {
+ ret = true;
+ }
+ }
+ return ret && data != 0;
+}
+
+QList<Atom> QXlibMime::mimeAtomsForFormat(Display *display, const QString &format)
+{
+ QList<Atom> atoms;
+ atoms.append(mimeStringToAtom(display, format));
+
+ // special cases for strings
+ if (format == QLatin1String("text/plain")) {
+ atoms.append(QXlibStatic::atom(QXlibStatic::UTF8_STRING));
+ atoms.append(XA_STRING);
+ atoms.append(QXlibStatic::atom(QXlibStatic::TEXT));
+ atoms.append(QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT));
+ }
+
+ // special cases for uris
+ if (format == QLatin1String("text/uri-list")) {
+ atoms.append(mimeStringToAtom(display,QLatin1String("text/x-moz-url")));
+ }
+
+ //special cases for images
+ if (format == QLatin1String("image/ppm"))
+ atoms.append(XA_PIXMAP);
+ if (format == QLatin1String("image/pbm"))
+ atoms.append(XA_BITMAP);
+
+ return atoms;
+}
+
+QVariant QXlibMime::mimeConvertToFormat(Display *display, Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding)
+{
+ QString atomName = mimeAtomToString(display,a);
+ if (atomName == format)
+ return 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 == QXlibStatic::atom(QXlibStatic::UTF8_STRING))
+ return QString::fromUtf8(data);
+ if (a == XA_STRING)
+ return QString::fromLatin1(data);
+ if (a == QXlibStatic::atom(QXlibStatic::TEXT)
+ || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT))
+ // #### might be wrong for COMPUND_TEXT
+ return QString::fromLocal8Bit(data, data.size());
+ }
+
+ // 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();
+ }
+ }
+
+ // special cas for images
+ if (format == QLatin1String("image/ppm")) {
+ if (a == XA_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();
+ }
+ }
+ return QVariant();
+}
+
+Atom QXlibMime::mimeAtomForFormat(Display *display, const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding)
+{
+ requestedEncoding->clear();
+
+ // find matches for string types
+ if (format == QLatin1String("text/plain")) {
+ if (atoms.contains(QXlibStatic::atom(QXlibStatic::UTF8_STRING)))
+ return QXlibStatic::atom(QXlibStatic::UTF8_STRING);
+ if (atoms.contains(QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)))
+ return QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT);
+ if (atoms.contains(QXlibStatic::atom(QXlibStatic::TEXT)))
+ return QXlibStatic::atom(QXlibStatic::TEXT);
+ if (atoms.contains(XA_STRING))
+ return XA_STRING;
+ }
+
+ // find matches for uri types
+ if (format == QLatin1String("text/uri-list")) {
+ Atom a = mimeStringToAtom(display,format);
+ if (a && atoms.contains(a))
+ return a;
+ a = mimeStringToAtom(display,QLatin1String("text/x-moz-url"));
+ if (a && atoms.contains(a))
+ return a;
+ }
+
+ // find match for image
+ if (format == QLatin1String("image/ppm")) {
+ if (atoms.contains(XA_PIXMAP))
+ return XA_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"));
+
+ Atom a = mimeStringToAtom(display,formatWithCharset);
+ if (a && atoms.contains(a)) {
+ *requestedEncoding = "utf-8";
+ return a;
+ }
+ }
+
+ Atom a = mimeStringToAtom(display,format);
+ if (a && atoms.contains(a))
+ return a;
+
+ return 0;
+}
diff --git a/src/plugins/platforms/xlib/qxlibmime.h b/src/plugins/platforms/xlib/qxlibmime.h
new file mode 100644
index 0000000000..a9bc265f5b
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibmime.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 QTESTLITEMIME_H
+#define QTESTLITEMIME_H
+
+#include <private/qdnd_p.h>
+
+#include <QtGui/QClipboard>
+
+#include "qxlibintegration.h"
+#include "qxlibclipboard.h"
+
+class QXlibMime : public QInternalMimeData {
+ Q_OBJECT
+public:
+ QXlibMime();
+ ~QXlibMime();
+
+ static QList<Atom> mimeAtomsForFormat(Display *display, const QString &format);
+ static QString mimeAtomToString(Display *display, Atom a);
+ static bool mimeDataForAtom(Display *display, Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat);
+ static QStringList mimeFormatsForAtom(Display *display, Atom a);
+ static Atom mimeStringToAtom(Display *display, const QString &mimeType);
+ static QVariant mimeConvertToFormat(Display *display, Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding);
+ static Atom mimeAtomForFormat(Display *display, const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding);
+};
+
+#endif // QTESTLITEMIME_H
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
new file mode 100644
index 0000000000..4e950ffe2f
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** 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 "qxlibnativeinterface.h"
+
+#include "qxlibdisplay.h"
+#include <QtGui/private/qapplication_p.h>
+
+class QXlibResourceMap : public QMap<QByteArray, QXlibNativeInterface::ResourceType>
+{
+public:
+ QXlibResourceMap()
+ :QMap<QByteArray, QXlibNativeInterface::ResourceType>()
+ {
+ insert("display",QXlibNativeInterface::Display);
+ insert("egldisplay",QXlibNativeInterface::EglDisplay);
+ insert("connection",QXlibNativeInterface::Connection);
+ insert("screen",QXlibNativeInterface::Screen);
+ insert("graphicsdevice",QXlibNativeInterface::GraphicsDevice);
+ insert("eglcontext",QXlibNativeInterface::EglContext);
+ }
+};
+
+Q_GLOBAL_STATIC(QXlibResourceMap, qXlibResourceMap)
+
+
+void * QXlibNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qXlibResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch(resource) {
+ case Display:
+ result = displayForWidget(widget);
+ break;
+ case EglDisplay:
+ result = eglDisplayForWidget(widget);
+ break;
+ case Connection:
+ result = connectionForWidget(widget);
+ break;
+ case Screen:
+ result = reinterpret_cast<void *>(qPlatformScreenForWidget(widget)->xScreenNumber());
+ break;
+ case GraphicsDevice:
+ result = graphicsDeviceForWidget(widget);
+ break;
+ case EglContext:
+ result = eglContextForWidget(widget);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+void * QXlibNativeInterface::displayForWidget(QWidget *widget)
+{
+ return qPlatformScreenForWidget(widget)->display()->nativeDisplay();
+}
+
+void * QXlibNativeInterface::eglDisplayForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+void * QXlibNativeInterface::screenForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+void * QXlibNativeInterface::graphicsDeviceForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+void * QXlibNativeInterface::eglContextForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+QXlibScreen * QXlibNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+{
+ QXlibScreen *screen;
+ if (widget) {
+ screen = static_cast<QXlibScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+ }else {
+ screen = static_cast<QXlibScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+ }
+ return screen;
+}
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.h b/src/plugins/platforms/xlib/qxlibnativeinterface.h
new file mode 100644
index 0000000000..5ba0768272
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.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$
+** 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 QXLIBNATIVEINTERFACE_H
+#define QXLIBNATIVEINTERFACE_H
+
+#include "qxlibscreen.h"
+
+#include <QtGui/QPlatformNativeInterface>
+
+class QXlibNativeInterface : public QPlatformNativeInterface
+{
+public:
+ enum ResourceType {
+ Display,
+ EglDisplay,
+ Connection,
+ Screen,
+ GraphicsDevice,
+ EglContext
+ };
+
+ void *nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget);
+
+ void *displayForWidget(QWidget *widget);
+ void *eglDisplayForWidget(QWidget *widget);
+ void *connectionForWidget(QWidget *widget);
+ void *screenForWidget(QWidget *widget);
+ void *graphicsDeviceForWidget(QWidget *widget);
+ void *eglContextForWidget(QWidget *widget);
+
+private:
+ static QXlibScreen *qPlatformScreenForWidget(QWidget *widget);
+};
+
+
+#endif // QXLIBNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp
new file mode 100644
index 0000000000..7c8a367373
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibscreen.cpp
@@ -0,0 +1,488 @@
+/****************************************************************************
+**
+** 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 "qxlibscreen.h"
+
+#include "qxlibcursor.h"
+#include "qxlibwindow.h"
+#include "qxlibkeyboard.h"
+#include "qxlibstatic.h"
+#include "qxlibclipboard.h"
+#include "qxlibdisplay.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QSocketNotifier>
+#include <QtCore/QElapsedTimer>
+
+#include <private/qapplication_p.h>
+
+#include <X11/extensions/Xfixes.h>
+
+QT_BEGIN_NAMESPACE
+
+static int (*original_x_errhandler)(Display *dpy, XErrorEvent *);
+static bool seen_badwindow;
+
+static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
+{
+
+qDebug() << "qt_x_errhandler" << err->error_code;
+
+ switch (err->error_code) {
+ case BadAtom:
+#if 0
+ if (err->request_code == 20 /* X_GetProperty */
+ && (err->resourceid == XA_RESOURCE_MANAGER
+ || err->resourceid == XA_RGB_DEFAULT_MAP
+ || err->resourceid == ATOM(_NET_SUPPORTED)
+ || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK)
+ || err->resourceid == ATOM(KDE_FULL_SESSION)
+ || err->resourceid == ATOM(KWIN_RUNNING)
+ || err->resourceid == ATOM(XdndProxy)
+ || err->resourceid == ATOM(XdndAware))
+
+
+ ) {
+ // Perhaps we're running under SECURITY reduction? :/
+ return 0;
+ }
+#endif
+ qDebug() << "BadAtom";
+ break;
+
+ case BadWindow:
+ if (err->request_code == 2 /* X_ChangeWindowAttributes */
+ || err->request_code == 38 /* X_QueryPointer */) {
+ for (int i = 0; i < ScreenCount(dpy); ++i) {
+ if (err->resourceid == RootWindow(dpy, i)) {
+ // Perhaps we're running under SECURITY reduction? :/
+ return 0;
+ }
+ }
+ }
+ seen_badwindow = true;
+ if (err->request_code == 25 /* X_SendEvent */) {
+ for (int i = 0; i < ScreenCount(dpy); ++i) {
+ if (err->resourceid == RootWindow(dpy, i)) {
+ // Perhaps we're running under SECURITY reduction? :/
+ return 0;
+ }
+ }
+#if 0
+ if (X11->xdndHandleBadwindow()) {
+ qDebug("xdndHandleBadwindow returned true");
+ return 0;
+ }
+#endif
+ }
+#if 0
+ if (X11->ignore_badwindow)
+ return 0;
+#endif
+ break;
+
+ case BadMatch:
+ if (err->request_code == 42 /* X_SetInputFocus */)
+ return 0;
+ break;
+
+ default:
+#if 0 //!defined(QT_NO_XINPUT)
+ if (err->request_code == X11->xinput_major
+ && err->error_code == (X11->xinput_errorbase + XI_BadDevice)
+ && err->minor_code == 3 /* X_OpenDevice */) {
+ return 0;
+ }
+#endif
+ break;
+ }
+
+ char errstr[256];
+ XGetErrorText( dpy, err->error_code, errstr, 256 );
+ char buffer[256];
+ char request_str[256];
+ qsnprintf(buffer, 256, "%d", err->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", buffer, "", request_str, 256);
+ if (err->request_code < 128) {
+ // X error for a normal protocol request
+ qWarning( "X Error: %s %d\n"
+ " Major opcode: %d (%s)\n"
+ " Resource id: 0x%lx",
+ errstr, err->error_code,
+ err->request_code,
+ request_str,
+ err->resourceid );
+ } else {
+ // X error for an extension request
+ const char *extensionName = 0;
+#if 0
+ if (err->request_code == X11->xrender_major)
+ extensionName = "RENDER";
+ else if (err->request_code == X11->xrandr_major)
+ extensionName = "RANDR";
+ else if (err->request_code == X11->xinput_major)
+ extensionName = "XInputExtension";
+ else if (err->request_code == X11->mitshm_major)
+ extensionName = "MIT-SHM";
+#endif
+ char minor_str[256];
+ if (extensionName) {
+ qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256);
+ } else {
+ extensionName = "Uknown extension";
+ qsnprintf(minor_str, 256, "Unknown request");
+ }
+ qWarning( "X Error: %s %d\n"
+ " Extension: %d (%s)\n"
+ " Minor opcode: %d (%s)\n"
+ " Resource id: 0x%lx",
+ errstr, err->error_code,
+ err->request_code,
+ extensionName,
+ err->minor_code,
+ minor_str,
+ err->resourceid );
+ }
+
+ // ### we really should distinguish between severe, non-severe and
+ // ### application specific errors
+
+ return 0;
+}
+
+QXlibScreen::QXlibScreen()
+ : mFormat(QImage::Format_RGB32)
+#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2)
+ , mEGLDisplay(0)
+#endif
+{
+ char *display_name = getenv("DISPLAY");
+ Display *display = XOpenDisplay(display_name);
+ mDisplay = new QXlibDisplay(display);
+
+
+#ifndef DONT_USE_MIT_SHM
+ Status MIT_SHM_extension_supported = XShmQueryExtension (mDisplay->nativeDisplay());
+ Q_ASSERT(MIT_SHM_extension_supported == True);
+#endif
+ original_x_errhandler = XSetErrorHandler(qt_x_errhandler);
+
+ if (qgetenv("DO_X_SYNCHRONIZE").toInt())
+ XSynchronize(mDisplay->nativeDisplay(), true);
+
+ mScreen = DefaultScreen(mDisplay->nativeDisplay());
+ XSelectInput(mDisplay->nativeDisplay(),rootWindow(), KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask);
+ int width = DisplayWidth(mDisplay->nativeDisplay(), mScreen);
+ int height = DisplayHeight(mDisplay->nativeDisplay(), mScreen);
+ mGeometry = QRect(0,0,width,height);
+
+ int physicalWidth = DisplayWidthMM(mDisplay->nativeDisplay(), mScreen);
+ int physicalHeight = DisplayHeightMM(mDisplay->nativeDisplay(), mScreen);
+ mPhysicalSize = QSize(physicalWidth,physicalHeight);
+
+ int xSocketNumber = XConnectionNumber(mDisplay->nativeDisplay());
+
+ mDepth = DefaultDepth(mDisplay->nativeDisplay(),mScreen);
+#ifdef MYX11_DEBUG
+ qDebug() << "X socket:"<< xSocketNumber;
+#endif
+ QSocketNotifier *sock = new QSocketNotifier(xSocketNumber, QSocketNotifier::Read, this);
+ connect(sock, SIGNAL(activated(int)), this, SLOT(eventDispatcher()));
+
+ mCursor = new QXlibCursor(this);
+ mKeyboard = new QXlibKeyboard(this);
+}
+
+QXlibScreen::~QXlibScreen()
+{
+ delete mCursor;
+ delete mDisplay;
+}
+
+Window QXlibScreen::rootWindow()
+{
+ return RootWindow(mDisplay->nativeDisplay(), mScreen);
+}
+
+unsigned long QXlibScreen::blackPixel()
+{
+ return BlackPixel(mDisplay->nativeDisplay(), mScreen);
+}
+
+unsigned long QXlibScreen::whitePixel()
+{
+ return WhitePixel(mDisplay->nativeDisplay(), mScreen);
+}
+
+#ifdef KeyPress
+#undef KeyPress
+#endif
+#ifdef KeyRelease
+#undef KeyRelease
+#endif
+
+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());
+ }
+
+ Atom wmProtocolsAtom = QXlibStatic::atom(QXlibStatic::WM_PROTOCOLS);
+ Atom wmDeleteWindowAtom = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW);
+ switch (xe->type) {
+
+ case ClientMessage:
+ if (xe->xclient.format == 32 && xe->xclient.message_type == wmProtocolsAtom) {
+ Atom a = xe->xclient.data.l[0];
+ if (a == wmDeleteWindowAtom)
+ platformWindow->handleCloseEvent();
+ }
+ break;
+
+ case Expose:
+ if (platformWindow)
+ if (xe->xexpose.count == 0)
+ platformWindow->paintEvent();
+ break;
+ case ConfigureNotify:
+ if (platformWindow)
+ platformWindow->resizeEvent(&xe->xconfigure);
+ break;
+
+ case ButtonPress:
+ if (platformWindow)
+ platformWindow->mousePressEvent(&xe->xbutton);
+ break;
+
+ case ButtonRelease:
+ if (platformWindow)
+ platformWindow->handleMouseEvent(QEvent::MouseButtonRelease, &xe->xbutton);
+ break;
+
+ case MotionNotify:
+ if (platformWindow)
+ platformWindow->handleMouseEvent(QEvent::MouseMove, &xe->xbutton);
+ break;
+
+ case XKeyPress:
+ mKeyboard->handleKeyEvent(widget,QEvent::KeyPress, &xe->xkey);
+ break;
+
+ case XKeyRelease:
+ mKeyboard->handleKeyEvent(widget,QEvent::KeyRelease, &xe->xkey);
+ break;
+
+ case EnterNotify:
+ if (platformWindow)
+ platformWindow->handleEnterEvent();
+ break;
+
+ case LeaveNotify:
+ if (platformWindow)
+ platformWindow->handleLeaveEvent();
+ break;
+
+ case XFocusIn:
+ if (platformWindow)
+ platformWindow->handleFocusInEvent();
+ break;
+
+ case XFocusOut:
+ if (platformWindow)
+ platformWindow->handleFocusOutEvent();
+ break;
+
+ case PropertyNotify:
+ break;
+
+ case SelectionClear:
+ qDebug() << "Selection Clear!!!";
+ break;
+ case SelectionRequest:
+ handleSelectionRequest(xe);
+ break;
+ case SelectionNotify:
+ qDebug() << "Selection Notify!!!!";
+
+ break;
+
+
+ default:
+#ifdef MYX11_DEBUG
+ qDebug() << hex << xe->xany.window << "Other X event" << xe->type;
+#endif
+ break;
+ }
+
+ return quit;
+}
+
+static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer)
+{
+ Atom clipboard = QXlibStatic::atom(QXlibStatic::CLIPBOARD);
+ return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY
+ || e->xselectionrequest.selection == clipboard))
+ || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY
+ || e->xselectionclear.selection == clipboard)));
+}
+
+bool QXlibScreen::waitForClipboardEvent(Window win, int type, XEvent *event, int timeout)
+{
+ QElapsedTimer timer;
+ timer.start();
+ do {
+ if (XCheckTypedWindowEvent(mDisplay->nativeDisplay(),win,type,event))
+ return true;
+
+ // process other clipboard events, since someone is probably requesting data from us
+ XEvent e;
+ if (XCheckIfEvent(mDisplay->nativeDisplay(), &e, checkForClipboardEvents, 0))
+ handleEvent(&e);
+
+ mDisplay->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 false;
+}
+
+void QXlibScreen::eventDispatcher()
+{
+ ulong marker = XNextRequest(mDisplay->nativeDisplay());
+ // int i = 0;
+ while (XPending(mDisplay->nativeDisplay())) {
+ XEvent event;
+ XNextEvent(mDisplay->nativeDisplay(), &event);
+ /* done = */
+ handleEvent(&event);
+
+ if (event.xany.serial >= marker) {
+ #ifdef MYX11_DEBUG
+ qDebug() << "potential livelock averted";
+ #endif
+ #if 0
+ if (XEventsQueued(mDisplay->nativeDisplay(), QueuedAfterFlush)) {
+ qDebug() << " with events queued";
+ QTimer::singleShot(0, this, SLOT(eventDispatcher()));
+ }
+ #endif
+ break;
+ }
+ }
+}
+
+QImage QXlibScreen::grabWindow(Window window, int x, int y, int w, int h)
+{
+ if (w == 0 || h ==0)
+ return QImage();
+
+ //WinId 0 means the desktop widget
+ if (!window)
+ window = rootWindow();
+
+ XWindowAttributes window_attr;
+ if (!XGetWindowAttributes(mDisplay->nativeDisplay(), window, &window_attr))
+ return QImage();
+
+ if (w < 0)
+ w = window_attr.width - x;
+ if (h < 0)
+ h = window_attr.height - y;
+
+ // Ideally, we should also limit ourselves to the screen area, but the Qt docs say
+ // that it's "unsafe" to go outside the screen, so we can ignore that problem.
+
+ //We're definitely not optimizing for speed...
+ XImage *xi = XGetImage(mDisplay->nativeDisplay(), window, x, y, w, h, AllPlanes, ZPixmap);
+
+ if (!xi)
+ return QImage();
+
+ //taking a copy to make sure we have ownership -- not fast
+ QImage result = QImage( (uchar*) xi->data, xi->width, xi->height, xi->bytes_per_line, QImage::Format_RGB32 ).copy();
+
+ XDestroyImage(xi);
+
+ return result;
+}
+
+QXlibScreen * QXlibScreen::testLiteScreenForWidget(QWidget *widget)
+{
+ QPlatformScreen *platformScreen = platformScreenForWidget(widget);
+ return static_cast<QXlibScreen *>(platformScreen);
+}
+
+QXlibDisplay * QXlibScreen::display() const
+{
+ return mDisplay;
+}
+
+int QXlibScreen::xScreenNumber() const
+{
+ return mScreen;
+}
+
+Visual * QXlibScreen::defaultVisual() const
+{
+ return DefaultVisual(display()->nativeDisplay(), xScreenNumber());
+}
+
+QXlibKeyboard * QXlibScreen::keyboard() const
+{
+ return mKeyboard;
+}
+
+void QXlibScreen::handleSelectionRequest(XEvent *event)
+{
+ QPlatformIntegration *integration = QApplicationPrivate::platformIntegration();
+ QXlibClipboard *clipboard = static_cast<QXlibClipboard *>(integration->clipboard());
+ clipboard->handleSelectionRequest(event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibscreen.h b/src/plugins/platforms/xlib/qxlibscreen.h
new file mode 100644
index 0000000000..8c04c0fb38
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibscreen.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 QTESTLITESCREEN_H
+#define QTESTLITESCREEN_H
+
+#include <QtGui/QPlatformScreen>
+#include "qxlibintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXlibCursor;
+class QXlibKeyboard;
+class QXlibDisplay;
+
+class QXlibScreen : public QPlatformScreen
+{
+ Q_OBJECT
+public:
+ QXlibScreen();
+
+ ~QXlibScreen();
+
+ QRect geometry() const { return mGeometry; }
+ int depth() const { return mDepth; }
+ QImage::Format format() const { return mFormat; }
+ QSize physicalSize() const { return mPhysicalSize; }
+
+ Window rootWindow();
+ unsigned long blackPixel();
+ unsigned long whitePixel();
+
+ bool handleEvent(XEvent *xe);
+ bool waitForClipboardEvent(Window win, int type, XEvent *event, int timeout);
+
+ QImage grabWindow(Window window, int x, int y, int w, int h);
+
+ static QXlibScreen *testLiteScreenForWidget(QWidget *widget);
+
+ QXlibDisplay *display() const;
+ int xScreenNumber() const;
+
+ Visual *defaultVisual() const;
+
+ QXlibKeyboard *keyboard() const;
+
+#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2)
+ void *eglDisplay() const { return mEGLDisplay; }
+ void setEglDisplay(void *display) { mEGLDisplay = display; }
+#endif
+
+public slots:
+ void eventDispatcher();
+
+private:
+
+ void handleSelectionRequest(XEvent *event);
+ QRect mGeometry;
+ QSize mPhysicalSize;
+ int mDepth;
+ QImage::Format mFormat;
+ QXlibCursor *mCursor;
+ QXlibKeyboard *mKeyboard;
+
+ QXlibDisplay * mDisplay;
+#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2)
+ void *mEGLDisplay;
+#endif
+ int mScreen;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTESTLITESCREEN_H
diff --git a/src/plugins/platforms/xlib/qxlibstatic.cpp b/src/plugins/platforms/xlib/qxlibstatic.cpp
new file mode 100644
index 0000000000..61177812d5
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibstatic.cpp
@@ -0,0 +1,512 @@
+/****************************************************************************
+**
+** 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 "qxlibstatic.h"
+#include "qxlibscreen.h"
+#include "qxlibdisplay.h"
+
+#include <qplatformdefs.h>
+
+#include <QtGui/private/qapplication_p.h>
+#include <QtCore/QBuffer>
+#include <QtCore/QLibrary>
+
+#include <QDebug>
+
+#ifndef QT_NO_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif // QT_NO_XFIXES
+
+static const char * x11_atomnames = {
+ // window-manager <-> client protocols
+ "WM_PROTOCOLS\0"
+ "WM_DELETE_WINDOW\0"
+ "WM_TAKE_FOCUS\0"
+ "_NET_WM_PING\0"
+ "_NET_WM_CONTEXT_HELP\0"
+ "_NET_WM_SYNC_REQUEST\0"
+ "_NET_WM_SYNC_REQUEST_COUNTER\0"
+
+ // ICCCM window state
+ "WM_STATE\0"
+ "WM_CHANGE_STATE\0"
+
+ // Session management
+ "WM_CLIENT_LEADER\0"
+ "WM_WINDOW_ROLE\0"
+ "SM_CLIENT_ID\0"
+
+ // Clipboard
+ "CLIPBOARD\0"
+ "INCR\0"
+ "TARGETS\0"
+ "MULTIPLE\0"
+ "TIMESTAMP\0"
+ "SAVE_TARGETS\0"
+ "CLIP_TEMPORARY\0"
+ "_QT_SELECTION\0"
+ "_QT_CLIPBOARD_SENTINEL\0"
+ "_QT_SELECTION_SENTINEL\0"
+ "CLIPBOARD_MANAGER\0"
+
+ "RESOURCE_MANAGER\0"
+
+ "_XSETROOT_ID\0"
+
+ "_QT_SCROLL_DONE\0"
+ "_QT_INPUT_ENCODING\0"
+
+ "_MOTIF_WM_HINTS\0"
+
+ "DTWM_IS_RUNNING\0"
+ "ENLIGHTENMENT_DESKTOP\0"
+ "_DT_SAVE_MODE\0"
+ "_SGI_DESKS_MANAGER\0"
+
+ // EWMH (aka NETWM)
+ "_NET_SUPPORTED\0"
+ "_NET_VIRTUAL_ROOTS\0"
+ "_NET_WORKAREA\0"
+
+ "_NET_MOVERESIZE_WINDOW\0"
+ "_NET_WM_MOVERESIZE\0"
+
+ "_NET_WM_NAME\0"
+ "_NET_WM_ICON_NAME\0"
+ "_NET_WM_ICON\0"
+
+ "_NET_WM_PID\0"
+
+ "_NET_WM_WINDOW_OPACITY\0"
+
+ "_NET_WM_STATE\0"
+ "_NET_WM_STATE_ABOVE\0"
+ "_NET_WM_STATE_BELOW\0"
+ "_NET_WM_STATE_FULLSCREEN\0"
+ "_NET_WM_STATE_MAXIMIZED_HORZ\0"
+ "_NET_WM_STATE_MAXIMIZED_VERT\0"
+ "_NET_WM_STATE_MODAL\0"
+ "_NET_WM_STATE_STAYS_ON_TOP\0"
+ "_NET_WM_STATE_DEMANDS_ATTENTION\0"
+
+ "_NET_WM_USER_TIME\0"
+ "_NET_WM_USER_TIME_WINDOW\0"
+ "_NET_WM_FULL_PLACEMENT\0"
+
+ "_NET_WM_WINDOW_TYPE\0"
+ "_NET_WM_WINDOW_TYPE_DESKTOP\0"
+ "_NET_WM_WINDOW_TYPE_DOCK\0"
+ "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
+ "_NET_WM_WINDOW_TYPE_MENU\0"
+ "_NET_WM_WINDOW_TYPE_UTILITY\0"
+ "_NET_WM_WINDOW_TYPE_SPLASH\0"
+ "_NET_WM_WINDOW_TYPE_DIALOG\0"
+ "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
+ "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
+ "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
+ "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
+ "_NET_WM_WINDOW_TYPE_COMBO\0"
+ "_NET_WM_WINDOW_TYPE_DND\0"
+ "_NET_WM_WINDOW_TYPE_NORMAL\0"
+ "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
+
+ "_KDE_NET_WM_FRAME_STRUT\0"
+
+ "_NET_STARTUP_INFO\0"
+ "_NET_STARTUP_INFO_BEGIN\0"
+
+ "_NET_SUPPORTING_WM_CHECK\0"
+
+ "_NET_WM_CM_S0\0"
+
+ "_NET_SYSTEM_TRAY_VISUAL\0"
+
+ "_NET_ACTIVE_WINDOW\0"
+
+ // Property formats
+ "COMPOUND_TEXT\0"
+ "TEXT\0"
+ "UTF8_STRING\0"
+
+ // xdnd
+ "XdndEnter\0"
+ "XdndPosition\0"
+ "XdndStatus\0"
+ "XdndLeave\0"
+ "XdndDrop\0"
+ "XdndFinished\0"
+ "XdndTypeList\0"
+ "XdndActionList\0"
+
+ "XdndSelection\0"
+
+ "XdndAware\0"
+ "XdndProxy\0"
+
+ "XdndActionCopy\0"
+ "XdndActionLink\0"
+ "XdndActionMove\0"
+ "XdndActionPrivate\0"
+
+ // Motif DND
+ "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
+ "_MOTIF_DRAG_INITIATOR_INFO\0"
+ "_MOTIF_DRAG_RECEIVER_INFO\0"
+ "_MOTIF_DRAG_WINDOW\0"
+ "_MOTIF_DRAG_TARGETS\0"
+
+ "XmTRANSFER_SUCCESS\0"
+ "XmTRANSFER_FAILURE\0"
+
+ // Xkb
+ "_XKB_RULES_NAMES\0"
+
+ // XEMBED
+ "_XEMBED\0"
+ "_XEMBED_INFO\0"
+
+ // Wacom old. (before version 0.10)
+ "Wacom Stylus\0"
+ "Wacom Cursor\0"
+ "Wacom Eraser\0"
+
+ // Tablet
+ "STYLUS\0"
+ "ERASER\0"
+};
+
+/*!
+ \internal
+ Try to resolve a \a symbol from \a library with the version specified
+ by \a vernum.
+
+ Note that, in the case of the Xfixes library, \a vernum is not the same as
+ \c XFIXES_MAJOR - it is a part of soname and may differ from the Xfixes
+ version.
+*/
+static void* qt_load_library_runtime(const char *library, int vernum,
+ int highestVernum, const char *symbol)
+{
+ QList<int> versions;
+ // we try to load in the following order:
+ // explicit version -> the default one -> (from the highest (highestVernum) to the lowest (vernum) )
+ if (vernum != -1)
+ versions << vernum;
+ versions << -1;
+ if (vernum != -1) {
+ for(int i = highestVernum; i > vernum; --i)
+ versions << i;
+ }
+ Q_FOREACH(int version, versions) {
+ QLatin1String libName(library);
+ QLibrary xfixesLib(libName, version);
+ void *ptr = xfixesLib.resolve(symbol);
+ if (ptr)
+ return ptr;
+ }
+ return 0;
+}
+
+# define XFIXES_LOAD_RUNTIME(vernum, symbol, symbol_type) \
+ (symbol_type)qt_load_library_runtime("libXfixes", vernum, 4, #symbol);
+# define XFIXES_LOAD_V1(symbol) \
+ XFIXES_LOAD_RUNTIME(1, symbol, Ptr##symbol)
+# define XFIXES_LOAD_V2(symbol) \
+ XFIXES_LOAD_RUNTIME(2, symbol, Ptr##symbol)
+
+
+class QTestLiteStaticInfoPrivate
+{
+public:
+ QTestLiteStaticInfoPrivate()
+ : use_xfixes(false)
+ , xfixes_major(0)
+ , xfixes_eventbase(0)
+ , xfixes_errorbase(0)
+ {
+ QXlibScreen *screen = qobject_cast<QXlibScreen *> (QApplicationPrivate::platformIntegration()->screens().at(0));
+ Q_ASSERT(screen);
+
+ initializeAllAtoms(screen);
+ initializeSupportedAtoms(screen);
+
+ resolveXFixes(screen);
+ }
+
+ bool isSupportedByWM(Atom atom)
+ {
+ if (!m_supportedAtoms)
+ return false;
+
+ bool supported = false;
+ int i = 0;
+ while (m_supportedAtoms[i] != 0) {
+ if (m_supportedAtoms[i++] == atom) {
+ supported = true;
+ break;
+ }
+ }
+
+ return supported;
+ }
+
+ Atom atom(QXlibStatic::X11Atom atom)
+ {
+ return m_allAtoms[atom];
+ }
+
+ bool useXFixes() const { return use_xfixes; }
+
+ int xFixesEventBase() const {return xfixes_eventbase; }
+
+ PtrXFixesSelectSelectionInput xFixesSelectSelectionInput() const
+ {
+ return ptrXFixesSelectSelectionInput;
+ }
+
+ QImage qimageFromXImage(XImage *xi)
+ {
+ QImage::Format format = QImage::Format_ARGB32_Premultiplied;
+ if (xi->depth == 24)
+ format = QImage::Format_RGB32;
+ else if (xi->depth == 16)
+ format = QImage::Format_RGB16;
+
+ QImage image = QImage((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format).copy();
+
+ // we may have to swap the byte order
+ if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
+ || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
+ {
+ for (int i=0; i < image.height(); i++) {
+ if (xi->depth == 16) {
+ ushort *p = (ushort*)image.scanLine(i);
+ ushort *end = p + image.width();
+ while (p < end) {
+ *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
+ p++;
+ }
+ } else {
+ 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++;
+ }
+ }
+ }
+ }
+
+ // fix-up alpha channel
+ if (format == QImage::Format_RGB32) {
+ QRgb *p = (QRgb *)image.bits();
+ for (int y = 0; y < xi->height; ++y) {
+ for (int x = 0; x < xi->width; ++x)
+ p[x] |= 0xff000000;
+ p += xi->bytes_per_line / 4;
+ }
+ }
+
+ return image;
+ }
+
+
+private:
+
+ void initializeAllAtoms(QXlibScreen *screen) {
+ const char *names[QXlibStatic::NAtoms];
+ const char *ptr = x11_atomnames;
+
+ int i = 0;
+ while (*ptr) {
+ names[i++] = ptr;
+ while (*ptr)
+ ++ptr;
+ ++ptr;
+ }
+
+ Q_ASSERT(i == QXlibStatic::NPredefinedAtoms);
+
+ QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
+ settings_atom_name += XDisplayName(qPrintable(screen->display()->displayName()));
+ names[i++] = settings_atom_name;
+
+ Q_ASSERT(i == QXlibStatic::NAtoms);
+ #if 0//defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
+ XInternAtoms(screen->display(), (char **)names, i, False, m_allAtoms);
+ #else
+ for (i = 0; i < QXlibStatic::NAtoms; ++i)
+ m_allAtoms[i] = XInternAtom(screen->display()->nativeDisplay(), (char *)names[i], False);
+ #endif
+ }
+
+ void initializeSupportedAtoms(QXlibScreen *screen)
+ {
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after;
+ unsigned char *data = 0;
+
+ int e = XGetWindowProperty(screen->display()->nativeDisplay(), screen->rootWindow(),
+ this->atom(QXlibStatic::_NET_SUPPORTED), 0, 0,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (e == Success && type == XA_ATOM && format == 32) {
+ QBuffer ts;
+ ts.open(QIODevice::WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(screen->display()->nativeDisplay(), screen->rootWindow(),
+ this->atom(QXlibStatic::_NET_SUPPORTED), offset, 1024,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+ if (type == XA_ATOM && format == 32) {
+ ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long));
+ offset += nitems;
+ } else
+ after = 0;
+ if (data)
+ XFree(data);
+ }
+
+ // compute nitems
+ QByteArray buffer(ts.buffer());
+ nitems = buffer.size() / sizeof(Atom);
+ m_supportedAtoms = new Atom[nitems + 1];
+ Atom *a = (Atom *) buffer.data();
+ uint i;
+ for (i = 0; i < nitems; i++)
+ m_supportedAtoms[i] = a[i];
+ m_supportedAtoms[nitems] = 0;
+
+ }
+ }
+
+ void resolveXFixes(QXlibScreen *screen)
+ {
+#ifndef QT_NO_XFIXES
+ // See if Xfixes is supported on the connected display
+ if (XQueryExtension(screen->display()->nativeDisplay(), "XFIXES", &xfixes_major,
+ &xfixes_eventbase, &xfixes_errorbase)) {
+ ptrXFixesQueryExtension = XFIXES_LOAD_V1(XFixesQueryExtension);
+ ptrXFixesQueryVersion = XFIXES_LOAD_V1(XFixesQueryVersion);
+ ptrXFixesSetCursorName = XFIXES_LOAD_V2(XFixesSetCursorName);
+ ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput);
+
+ if(ptrXFixesQueryExtension && ptrXFixesQueryVersion
+ && ptrXFixesQueryExtension(screen->display()->nativeDisplay(), &xfixes_eventbase,
+ &xfixes_errorbase)) {
+ // Xfixes is supported.
+ // Note: the XFixes protocol version is negotiated using QueryVersion.
+ // We supply the highest version we support, the X server replies with
+ // the highest version it supports, but no higher than the version we
+ // asked for. The version sent back is the protocol version the X server
+ // will use to talk us. If this call is removed, the behavior of the
+ // X server when it receives an XFixes request is undefined.
+ int major = 3;
+ int minor = 0;
+ ptrXFixesQueryVersion(screen->display()->nativeDisplay(), &major, &minor);
+ use_xfixes = (major >= 1);
+ xfixes_major = major;
+ }
+ }
+#endif // QT_NO_XFIXES
+
+ }
+
+ Atom *m_supportedAtoms;
+ Atom m_allAtoms[QXlibStatic::NAtoms];
+
+#ifndef QT_NO_XFIXES
+ PtrXFixesQueryExtension ptrXFixesQueryExtension;
+ PtrXFixesQueryVersion ptrXFixesQueryVersion;
+ PtrXFixesSetCursorName ptrXFixesSetCursorName;
+ PtrXFixesSelectSelectionInput ptrXFixesSelectSelectionInput;
+#endif
+
+ bool use_xfixes;
+ int xfixes_major;
+ int xfixes_eventbase;
+ int xfixes_errorbase;
+
+};
+Q_GLOBAL_STATIC(QTestLiteStaticInfoPrivate, qTestLiteStaticInfoPrivate);
+
+
+Atom QXlibStatic::atom(QXlibStatic::X11Atom atom)
+{
+ return qTestLiteStaticInfoPrivate()->atom(atom);
+}
+
+bool QXlibStatic::isSupportedByWM(Atom atom)
+{
+ return qTestLiteStaticInfoPrivate()->isSupportedByWM(atom);
+}
+
+bool QXlibStatic::useXFixes()
+{
+ return qTestLiteStaticInfoPrivate()->useXFixes();
+}
+
+int QXlibStatic::xFixesEventBase()
+{
+ return qTestLiteStaticInfoPrivate()->xFixesEventBase();
+}
+
+#ifndef QT_NO_XFIXES
+PtrXFixesSelectSelectionInput QXlibStatic::xFixesSelectSelectionInput()
+{
+ qDebug() << qTestLiteStaticInfoPrivate()->useXFixes();
+ if (!qTestLiteStaticInfoPrivate()->useXFixes())
+ return 0;
+
+ return qTestLiteStaticInfoPrivate()->xFixesSelectSelectionInput();
+}
+
+QImage QXlibStatic::qimageFromXImage(XImage *xi)
+{
+ return qTestLiteStaticInfoPrivate()->qimageFromXImage(xi);
+}
+#endif //QT_NO_XFIXES
diff --git a/src/plugins/platforms/xlib/qxlibstatic.h b/src/plugins/platforms/xlib/qxlibstatic.h
new file mode 100644
index 0000000000..72cfaec54c
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibstatic.h
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** 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 QTESTLITESTATICINFO_H
+#define QTESTLITESTATICINFO_H
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+
+#if defined(_XLIB_H_) // crude hack, but...
+#error "cannot include <X11/Xlib.h> before this file"
+#endif
+#define XRegisterIMInstantiateCallback qt_XRegisterIMInstantiateCallback
+#define XUnregisterIMInstantiateCallback qt_XUnregisterIMInstantiateCallback
+#define XSetIMValues qt_XSetIMValues
+#include <X11/Xlib.h>
+#undef XRegisterIMInstantiateCallback
+#undef XUnregisterIMInstantiateCallback
+#undef XSetIMValues
+
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#ifdef index
+# undef index
+#endif
+#ifdef rindex
+# undef rindex
+#endif
+#ifdef Q_OS_VXWORS
+# ifdef open
+# undef open
+# endif
+# ifdef getpid
+# undef getpid
+# endif
+#endif // Q_OS_VXWORKS
+#include <X11/Xatom.h>
+
+//#define QT_NO_SHAPE
+#ifdef QT_NO_SHAPE
+# define XShapeCombineRegion(a,b,c,d,e,f,g)
+# define XShapeCombineMask(a,b,c,d,e,f,g)
+#else
+# include <X11/extensions/shape.h>
+#endif // QT_NO_SHAPE
+
+
+#if !defined (QT_NO_TABLET)
+# include <X11/extensions/XInput.h>
+#if defined (Q_OS_IRIX)
+# include <X11/extensions/SGIMisc.h>
+# include <wacom.h>
+#endif
+#endif // QT_NO_TABLET
+
+
+// #define QT_NO_XINERAMA
+#ifndef QT_NO_XINERAMA
+// XFree86 does not C++ify Xinerama (at least up to XFree86 4.0.3).
+extern "C" {
+# include <X11/extensions/Xinerama.h>
+}
+#endif // QT_NO_XINERAMA
+
+// #define QT_NO_XRANDR
+#ifndef QT_NO_XRANDR
+# include <X11/extensions/Xrandr.h>
+#endif // QT_NO_XRANDR
+
+// #define QT_NO_XRENDER
+#ifndef QT_NO_XRENDER
+# include <X11/extensions/Xrender.h>
+#endif // QT_NO_XRENDER
+
+#ifndef QT_NO_XSYNC
+extern "C" {
+# include "X11/extensions/sync.h"
+}
+#endif
+
+// #define QT_NO_XKB
+#ifndef QT_NO_XKB
+# include <X11/XKBlib.h>
+#endif // QT_NO_XKB
+
+
+#if !defined(XlibSpecificationRelease)
+# define X11R4
+typedef char *XPointer;
+#else
+# undef X11R4
+#endif
+
+#ifndef QT_NO_XFIXES
+typedef Bool (*PtrXFixesQueryExtension)(Display *, int *, int *);
+typedef Status (*PtrXFixesQueryVersion)(Display *, int *, int *);
+typedef void (*PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name);
+typedef void (*PtrXFixesSelectSelectionInput)(Display *dpy, Window win, Atom selection, unsigned long eventMask);
+#endif // QT_NO_XFIXES
+
+#ifndef QT_NO_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+typedef Cursor (*PtrXcursorLibraryLoadCursor)(Display *, const char *);
+#endif // QT_NO_XCURSOR
+
+#ifndef QT_NO_XINERAMA
+typedef Bool (*PtrXineramaQueryExtension)(Display *dpy, int *event_base, int *error_base);
+typedef Bool (*PtrXineramaIsActive)(Display *dpy);
+typedef XineramaScreenInfo *(*PtrXineramaQueryScreens)(Display *dpy, int *number);
+#endif // QT_NO_XINERAMA
+
+#ifndef QT_NO_XRANDR
+typedef void (*PtrXRRSelectInput)(Display *, Window, int);
+typedef int (*PtrXRRUpdateConfiguration)(XEvent *);
+typedef int (*PtrXRRRootToScreen)(Display *, Window);
+typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *);
+#endif // QT_NO_XRANDR
+
+#ifndef QT_NO_XINPUT
+typedef int (*PtrXCloseDevice)(Display *, XDevice *);
+typedef XDeviceInfo* (*PtrXListInputDevices)(Display *, int *);
+typedef XDevice* (*PtrXOpenDevice)(Display *, XID);
+typedef void (*PtrXFreeDeviceList)(XDeviceInfo *);
+typedef int (*PtrXSelectExtensionEvent)(Display *, Window, XEventClass *, int);
+#endif // QT_NO_XINPUT
+
+/*
+ * Solaris patch 108652-47 and higher fixes crases in
+ * XRegisterIMInstantiateCallback, but the function doesn't seem to
+ * work.
+ *
+ * Instead, we disabled R6 input, and open the input method
+ * immediately at application start.
+ */
+
+//######### XFree86 has wrong declarations for XRegisterIMInstantiateCallback
+//######### and XUnregisterIMInstantiateCallback in at least version 3.3.2.
+//######### Many old X11R6 header files lack XSetIMValues.
+//######### Therefore, we have to declare these functions ourselves.
+
+extern "C" Bool XRegisterIMInstantiateCallback(
+ Display*,
+ struct _XrmHashBucketRec*,
+ char*,
+ char*,
+ XIMProc, //XFree86 has XIDProc, which has to be wrong
+ XPointer
+);
+
+extern "C" Bool XUnregisterIMInstantiateCallback(
+ Display*,
+ struct _XrmHashBucketRec*,
+ char*,
+ char*,
+ XIMProc, //XFree86 has XIDProc, which has to be wrong
+ XPointer
+);
+
+#ifndef X11R4
+# include <X11/Xlocale.h>
+#endif // X11R4
+
+
+#ifndef QT_NO_MITSHM
+# include <X11/extensions/XShm.h>
+#endif // QT_NO_MITSHM
+
+// rename a couple of X defines to get rid of name clashes
+// resolve the conflict between X11's FocusIn and QEvent::FocusIn
+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
+
+
+class QXlibStatic
+{
+public:
+ enum X11Atom {
+ // window-manager <-> client protocols
+ WM_PROTOCOLS,
+ WM_DELETE_WINDOW,
+ WM_TAKE_FOCUS,
+ _NET_WM_PING,
+ _NET_WM_CONTEXT_HELP,
+ _NET_WM_SYNC_REQUEST,
+ _NET_WM_SYNC_REQUEST_COUNTER,
+
+ // ICCCM window state
+ WM_STATE,
+ WM_CHANGE_STATE,
+
+ // Session management
+ WM_CLIENT_LEADER,
+ WM_WINDOW_ROLE,
+ SM_CLIENT_ID,
+
+ // Clipboard
+ CLIPBOARD,
+ INCR,
+ TARGETS,
+ MULTIPLE,
+ TIMESTAMP,
+ SAVE_TARGETS,
+ CLIP_TEMPORARY,
+ _QT_SELECTION,
+ _QT_CLIPBOARD_SENTINEL,
+ _QT_SELECTION_SENTINEL,
+ CLIPBOARD_MANAGER,
+
+ RESOURCE_MANAGER,
+
+ _XSETROOT_ID,
+
+ _QT_SCROLL_DONE,
+ _QT_INPUT_ENCODING,
+
+ _MOTIF_WM_HINTS,
+
+ DTWM_IS_RUNNING,
+ ENLIGHTENMENT_DESKTOP,
+ _DT_SAVE_MODE,
+ _SGI_DESKS_MANAGER,
+
+ // EWMH (aka NETWM)
+ _NET_SUPPORTED,
+ _NET_VIRTUAL_ROOTS,
+ _NET_WORKAREA,
+
+ _NET_MOVERESIZE_WINDOW,
+ _NET_WM_MOVERESIZE,
+
+ _NET_WM_NAME,
+ _NET_WM_ICON_NAME,
+ _NET_WM_ICON,
+
+ _NET_WM_PID,
+
+ _NET_WM_WINDOW_OPACITY,
+
+ _NET_WM_STATE,
+ _NET_WM_STATE_ABOVE,
+ _NET_WM_STATE_BELOW,
+ _NET_WM_STATE_FULLSCREEN,
+ _NET_WM_STATE_MAXIMIZED_HORZ,
+ _NET_WM_STATE_MAXIMIZED_VERT,
+ _NET_WM_STATE_MODAL,
+ _NET_WM_STATE_STAYS_ON_TOP,
+ _NET_WM_STATE_DEMANDS_ATTENTION,
+
+ _NET_WM_USER_TIME,
+ _NET_WM_USER_TIME_WINDOW,
+ _NET_WM_FULL_PLACEMENT,
+
+ _NET_WM_WINDOW_TYPE,
+ _NET_WM_WINDOW_TYPE_DESKTOP,
+ _NET_WM_WINDOW_TYPE_DOCK,
+ _NET_WM_WINDOW_TYPE_TOOLBAR,
+ _NET_WM_WINDOW_TYPE_MENU,
+ _NET_WM_WINDOW_TYPE_UTILITY,
+ _NET_WM_WINDOW_TYPE_SPLASH,
+ _NET_WM_WINDOW_TYPE_DIALOG,
+ _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
+ _NET_WM_WINDOW_TYPE_POPUP_MENU,
+ _NET_WM_WINDOW_TYPE_TOOLTIP,
+ _NET_WM_WINDOW_TYPE_NOTIFICATION,
+ _NET_WM_WINDOW_TYPE_COMBO,
+ _NET_WM_WINDOW_TYPE_DND,
+ _NET_WM_WINDOW_TYPE_NORMAL,
+ _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
+
+ _KDE_NET_WM_FRAME_STRUT,
+
+ _NET_STARTUP_INFO,
+ _NET_STARTUP_INFO_BEGIN,
+
+ _NET_SUPPORTING_WM_CHECK,
+
+ _NET_WM_CM_S0,
+
+ _NET_SYSTEM_TRAY_VISUAL,
+
+ _NET_ACTIVE_WINDOW,
+
+ // Property formats
+ COMPOUND_TEXT,
+ TEXT,
+ UTF8_STRING,
+
+ // Xdnd
+ XdndEnter,
+ XdndPosition,
+ XdndStatus,
+ XdndLeave,
+ XdndDrop,
+ XdndFinished,
+ XdndTypelist,
+ XdndActionList,
+
+ XdndSelection,
+
+ XdndAware,
+ XdndProxy,
+
+ XdndActionCopy,
+ XdndActionLink,
+ XdndActionMove,
+ XdndActionPrivate,
+
+ // Motif DND
+ _MOTIF_DRAG_AND_DROP_MESSAGE,
+ _MOTIF_DRAG_INITIATOR_INFO,
+ _MOTIF_DRAG_RECEIVER_INFO,
+ _MOTIF_DRAG_WINDOW,
+ _MOTIF_DRAG_TARGETS,
+
+ XmTRANSFER_SUCCESS,
+ XmTRANSFER_FAILURE,
+
+ // Xkb
+ _XKB_RULES_NAMES,
+
+ // XEMBED
+ _XEMBED,
+ _XEMBED_INFO,
+
+ XWacomStylus,
+ XWacomCursor,
+ XWacomEraser,
+
+ XTabletStylus,
+ XTabletEraser,
+
+ NPredefinedAtoms,
+
+ _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
+ NAtoms
+ };
+
+ static Atom atom(X11Atom atom);
+ static bool isSupportedByWM(Atom atom);
+
+ static bool useXFixes();
+ static int xFixesEventBase();
+
+ #ifndef QT_NO_XFIXES
+ static PtrXFixesSelectSelectionInput xFixesSelectSelectionInput();
+ #endif //QT_NO_XFIXES
+
+ static QImage qimageFromXImage(XImage *xi);
+
+
+};
+
+#endif // QTESTLITESTATICINFO_H
diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp
new file mode 100644
index 0000000000..9a05fc620d
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibwindow.cpp
@@ -0,0 +1,737 @@
+/****************************************************************************
+**
+** 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 "qxlibwindow.h"
+
+#include "qxlibintegration.h"
+#include "qxlibscreen.h"
+#include "qxlibkeyboard.h"
+#include "qxlibstatic.h"
+#include "qxlibdisplay.h"
+
+#include <QtGui/QWindowSystemInterface>
+#include <QSocketNotifier>
+#include <QApplication>
+#include <QDebug>
+
+#include <QtGui/private/qwindowsurface_p.h>
+#include <QtGui/private/qapplication_p.h>
+
+#if !defined(QT_NO_OPENGL)
+#if !defined(QT_OPENGL_ES_2)
+#include "qglxintegration.h"
+#include "qglxconvenience.h"
+#else
+#include "../eglconvenience/qeglconvenience.h"
+#include "../eglconvenience/qeglplatformcontext.h"
+#include "../eglconvenience/qxlibeglintegration.h"
+#endif //QT_OPENGL_ES_2
+#endif //QT_NO_OPENGL
+
+//#define MYX11_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+QXlibWindow::QXlibWindow(QWidget *window)
+ : QPlatformWindow(window)
+ , mGLContext(0)
+ , mScreen(QXlibScreen::testLiteScreenForWidget(window))
+{
+ int x = window->x();
+ int y = window->y();
+ int w = window->width();
+ int h = window->height();
+
+ if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
+ && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) ) {
+#if !defined(QT_NO_OPENGL)
+#if !defined(QT_OPENGL_ES_2)
+ XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat());
+#else
+ QPlatformWindowFormat windowFormat = correctColorBuffers(window->platformWindowFormat());
+
+ EGLDisplay eglDisplay = mScreen->eglDisplay();
+ EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,windowFormat);
+ VisualID id = QXlibEglIntegration::getCompatibleVisualId(mScreen->display()->nativeDisplay(), eglDisplay, eglConfig);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = id;
+
+ XVisualInfo *visualInfo;
+ int matchingCount = 0;
+ visualInfo = XGetVisualInfo(mScreen->display()->nativeDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
+#endif //!defined(QT_OPENGL_ES_2)
+ if (visualInfo) {
+ Colormap cmap = XCreateColormap(mScreen->display()->nativeDisplay(),mScreen->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ x_window = XCreateWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),x, y, w, h,
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+ } else {
+ qFatal("no window!");
+ }
+#endif //!defined(QT_NO_OPENGL)
+ } else {
+ x_window = XCreateSimpleWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),
+ x, y, w, h, 0 /*border_width*/,
+ mScreen->blackPixel(), mScreen->whitePixel());
+ }
+
+#ifdef MYX11_DEBUG
+ qDebug() << "QTestLiteWindow::QTestLiteWindow creating" << hex << x_window << window;
+#endif
+
+ XSetWindowBackgroundPixmap(mScreen->display()->nativeDisplay(), x_window, XNone);
+
+ XSelectInput(mScreen->display()->nativeDisplay(), x_window,
+ ExposureMask | KeyPressMask | KeyReleaseMask |
+ EnterWindowMask | LeaveWindowMask | FocusChangeMask |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask | PropertyChangeMask |
+ StructureNotifyMask);
+
+ gc = createGC();
+
+ Atom protocols[5];
+ int n = 0;
+ protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW); // support del window protocol
+ protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_TAKE_FOCUS); // support take focus window protocol
+// protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_PING); // support _NET_WM_PING protocol
+#ifndef QT_NO_XSYNC
+ protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol
+#endif // QT_NO_XSYNC
+ if (window->windowFlags() & Qt::WindowContextHelpButtonHint)
+ protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_CONTEXT_HELP);
+ XSetWMProtocols(mScreen->display()->nativeDisplay(), x_window, protocols, n);
+}
+
+
+
+QXlibWindow::~QXlibWindow()
+{
+#ifdef MYX11_DEBUG
+ qDebug() << "~QTestLiteWindow" << hex << x_window;
+#endif
+ delete mGLContext;
+ XFreeGC(mScreen->display()->nativeDisplay(), gc);
+ XDestroyWindow(mScreen->display()->nativeDisplay(), x_window);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Mouse event stuff
+static Qt::MouseButtons translateMouseButtons(int s)
+{
+ Qt::MouseButtons ret = 0;
+ if (s & Button1Mask)
+ ret |= Qt::LeftButton;
+ if (s & Button2Mask)
+ ret |= Qt::MidButton;
+ if (s & Button3Mask)
+ ret |= Qt::RightButton;
+ return ret;
+}
+
+
+
+void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e)
+{
+ static QPoint mousePoint;
+
+ Qt::MouseButton button = Qt::NoButton;
+ Qt::MouseButtons buttons = translateMouseButtons(e->state);
+ Qt::KeyboardModifiers modifiers = mScreen->keyboard()->translateModifiers(e->state);
+ if (type != QEvent::MouseMove) {
+ switch (e->button) {
+ case Button1: button = Qt::LeftButton; break;
+ case Button2: button = Qt::MidButton; break;
+ case Button3: button = Qt::RightButton; break;
+ case Button4:
+ case Button5:
+ case 6:
+ case 7: {
+ //mouse wheel
+ if (type == QEvent::MouseButtonPress) {
+ //logic borrowed from qapplication_x11.cpp
+ int delta = 120 * ((e->button == Button4 || e->button == 6) ? 1 : -1);
+ bool hor = (((e->button == Button4 || e->button == Button5)
+ && (modifiers & Qt::AltModifier))
+ || (e->button == 6 || e->button == 7));
+ QWindowSystemInterface::handleWheelEvent(widget(), e->time,
+ QPoint(e->x, e->y),
+ QPoint(e->x_root, e->y_root),
+ delta, hor ? Qt::Horizontal : Qt::Vertical);
+ }
+ return;
+ }
+ default: break;
+ }
+ }
+
+ buttons ^= button; // X event uses state *before*, Qt uses state *after*
+
+ QWindowSystemInterface::handleMouseEvent(widget(), e->time, QPoint(e->x, e->y),
+ QPoint(e->x_root, e->y_root),
+ buttons);
+
+ mousePoint = QPoint(e->x_root, e->y_root);
+}
+
+void QXlibWindow::handleCloseEvent()
+{
+ QWindowSystemInterface::handleCloseEvent(widget());
+}
+
+
+void QXlibWindow::handleEnterEvent()
+{
+ QWindowSystemInterface::handleEnterEvent(widget());
+}
+
+void QXlibWindow::handleLeaveEvent()
+{
+ QWindowSystemInterface::handleLeaveEvent(widget());
+}
+
+void QXlibWindow::handleFocusInEvent()
+{
+ QWindowSystemInterface::handleWindowActivated(widget());
+}
+
+void QXlibWindow::handleFocusOutEvent()
+{
+ QWindowSystemInterface::handleWindowActivated(0);
+}
+
+
+
+void QXlibWindow::setGeometry(const QRect &rect)
+{
+ XMoveResizeWindow(mScreen->display()->nativeDisplay(), x_window, rect.x(), rect.y(), rect.width(), rect.height());
+ QPlatformWindow::setGeometry(rect);
+}
+
+
+Qt::WindowFlags QXlibWindow::windowFlags() const
+{
+ return mWindowFlags;
+}
+
+WId QXlibWindow::winId() const
+{
+ return x_window;
+}
+
+void QXlibWindow::setParent(const QPlatformWindow *window)
+{
+ QPoint topLeft = geometry().topLeft();
+ XReparentWindow(mScreen->display()->nativeDisplay(),x_window,window->winId(),topLeft.x(),topLeft.y());
+}
+
+void QXlibWindow::raise()
+{
+ XRaiseWindow(mScreen->display()->nativeDisplay(), x_window);
+}
+
+void QXlibWindow::lower()
+{
+ XLowerWindow(mScreen->display()->nativeDisplay(), x_window);
+}
+
+void QXlibWindow::setWindowTitle(const QString &title)
+{
+ QByteArray ba = title.toLatin1(); //We're not making a general solution here...
+ XTextProperty windowName;
+ windowName.value = (unsigned char *)ba.constData();
+ windowName.encoding = XA_STRING;
+ windowName.format = 8;
+ windowName.nitems = ba.length();
+
+ XSetWMName(mScreen->display()->nativeDisplay(), x_window, &windowName);
+}
+
+GC QXlibWindow::createGC()
+{
+ GC gc;
+
+ gc = XCreateGC(mScreen->display()->nativeDisplay(), x_window, 0, 0);
+ if (gc < 0) {
+ qWarning("QTestLiteWindow::createGC() could not create GC");
+ }
+ 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);
+}
+
+void QXlibWindow::resizeEvent(XConfigureEvent *e)
+{
+ int xpos = geometry().x();
+ int ypos = geometry().y();
+ if ((e->width != geometry().width() || e->height != geometry().height()) && e->x == 0 && e->y == 0) {
+ //qDebug() << "resize with bogus pos" << e->x << e->y << e->width << e->height << "window"<< hex << window;
+ } else {
+ //qDebug() << "geometry change" << e->x << e->y << e->width << e->height << "window"<< hex << window;
+ xpos = e->x;
+ 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;
+#endif
+
+ QRect newRect(xpos, ypos, e->width, e->height);
+ QWindowSystemInterface::handleGeometryChange(widget(), newRect);
+}
+
+void QXlibWindow::mousePressEvent(XButtonEvent *e)
+{
+ static long prevTime = 0;
+ static Window prevWindow;
+ static int prevX = -999;
+ static int prevY = -999;
+
+ QEvent::Type type = QEvent::MouseButtonPress;
+
+ if (e->window == prevWindow && long(e->time) - prevTime < QApplication::doubleClickInterval()
+ && qAbs(e->x - prevX) < 5 && qAbs(e->y - prevY) < 5) {
+ type = QEvent::MouseButtonDblClick;
+ prevTime = e->time - QApplication::doubleClickInterval(); //no double click next time
+ } else {
+ prevTime = e->time;
+ }
+ prevWindow = e->window;
+ prevX = e->x;
+ prevY = e->y;
+
+ handleMouseEvent(type, e);
+}
+
+QXlibMWMHints QXlibWindow::getMWMHints() const
+{
+ QXlibMWMHints mwmhints;
+
+ Atom type;
+ int format;
+ ulong nitems, bytesLeft;
+ uchar *data = 0;
+ Atom atomForMotifWmHints = QXlibStatic::atom(QXlibStatic::_MOTIF_WM_HINTS);
+ if ((XGetWindowProperty(mScreen->display()->nativeDisplay(), x_window, atomForMotifWmHints, 0, 5, false,
+ atomForMotifWmHints, &type, &format, &nitems, &bytesLeft,
+ &data) == Success)
+ && (type == atomForMotifWmHints
+ && format == 32
+ && nitems >= 5)) {
+ mwmhints = *(reinterpret_cast<QXlibMWMHints *>(data));
+ } else {
+ mwmhints.flags = 0L;
+ mwmhints.functions = MWM_FUNC_ALL;
+ mwmhints.decorations = MWM_DECOR_ALL;
+ mwmhints.input_mode = 0L;
+ mwmhints.status = 0L;
+ }
+
+ if (data)
+ XFree(data);
+
+ return mwmhints;
+}
+
+void QXlibWindow::setMWMHints(const QXlibMWMHints &mwmhints)
+{
+ Atom atomForMotifWmHints = QXlibStatic::atom(QXlibStatic::_MOTIF_WM_HINTS);
+ if (mwmhints.flags != 0l) {
+ XChangeProperty(mScreen->display()->nativeDisplay(), x_window,
+ atomForMotifWmHints, atomForMotifWmHints, 32,
+ PropModeReplace, (unsigned char *) &mwmhints, 5);
+ } else {
+ XDeleteProperty(mScreen->display()->nativeDisplay(), x_window, atomForMotifWmHints);
+ }
+}
+
+// Returns true if we should set WM_TRANSIENT_FOR on \a w
+static inline bool isTransient(const QWidget *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));
+}
+
+QVector<Atom> QXlibWindow::getNetWmState() const
+{
+ QVector<Atom> returnValue;
+
+ // Don't read anything, just get the size of the property data
+ Atom actualType;
+ int actualFormat;
+ ulong propertyLength;
+ ulong bytesLeft;
+ uchar *propertyData = 0;
+ if (XGetWindowProperty(mScreen->display()->nativeDisplay(), x_window, QXlibStatic::atom(QXlibStatic::_NET_WM_STATE), 0, 0,
+ False, XA_ATOM, &actualType, &actualFormat,
+ &propertyLength, &bytesLeft, &propertyData) == Success
+ && actualType == XA_ATOM && actualFormat == 32) {
+ returnValue.resize(bytesLeft / 4);
+ XFree((char*) propertyData);
+
+ // fetch all data
+ if (XGetWindowProperty(mScreen->display()->nativeDisplay(), x_window, QXlibStatic::atom(QXlibStatic::_NET_WM_STATE), 0,
+ returnValue.size(), False, XA_ATOM, &actualType, &actualFormat,
+ &propertyLength, &bytesLeft, &propertyData) != Success) {
+ returnValue.clear();
+ } else if (propertyLength != (ulong)returnValue.size()) {
+ returnValue.resize(propertyLength);
+ }
+
+ // put it into netWmState
+ if (!returnValue.isEmpty()) {
+ memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
+ }
+ XFree((char*) propertyData);
+ }
+
+ return returnValue;
+}
+
+Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+// Q_ASSERT(flags & Qt::Window);
+ mWindowFlags = flags;
+
+#ifdef MYX11_DEBUG
+ qDebug() << "QTestLiteWindow::setWindowFlags" << hex << x_window << "flags" << flags;
+#endif
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ 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);
+
+ Q_UNUSED(topLevel);
+ Q_UNUSED(dialog);
+ Q_UNUSED(desktop);
+
+ bool tooltip = (type == Qt::ToolTip);
+
+ XSetWindowAttributes wsa;
+
+ QXlibMWMHints mwmhints;
+ mwmhints.flags = 0L;
+ mwmhints.functions = 0L;
+ mwmhints.decorations = 0;
+ mwmhints.input_mode = 0L;
+ mwmhints.status = 0L;
+
+
+ ulong wsa_mask = 0;
+ if (type != Qt::SplashScreen) { // && customize) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+
+ bool customize = flags & Qt::CustomizeWindowHint;
+ if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
+ mwmhints.decorations |= MWM_DECOR_BORDER;
+ mwmhints.decorations |= MWM_DECOR_RESIZEH;
+
+ if (flags & Qt::WindowTitleHint)
+ mwmhints.decorations |= MWM_DECOR_TITLE;
+
+ if (flags & Qt::WindowSystemMenuHint)
+ mwmhints.decorations |= MWM_DECOR_MENU;
+
+ if (flags & Qt::WindowMinimizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+ mwmhints.functions |= MWM_FUNC_MINIMIZE;
+ }
+
+ if (flags & Qt::WindowMaximizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+ mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+ }
+
+ if (flags & Qt::WindowCloseButtonHint)
+ mwmhints.functions |= MWM_FUNC_CLOSE;
+ }
+ } else {
+ // if type == Qt::SplashScreen
+ mwmhints.decorations = MWM_DECOR_ALL;
+ }
+
+ if (tool) {
+ wsa.save_under = True;
+ wsa_mask |= CWSaveUnder;
+ }
+
+ if (flags & Qt::X11BypassWindowManagerHint) {
+ wsa.override_redirect = True;
+ wsa_mask |= CWOverrideRedirect;
+ }
+#if 0
+ if (wsa_mask && initializeWindow) {
+ Q_ASSERT(id);
+ XChangeWindowAttributes(dpy, id, wsa_mask, &wsa);
+ }
+#endif
+ if (mwmhints.functions != 0) {
+ mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+ mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ } else {
+ mwmhints.functions = MWM_FUNC_ALL;
+ }
+
+ if (!(flags & Qt::FramelessWindowHint)
+ && flags & Qt::CustomizeWindowHint
+ && flags & Qt::WindowTitleHint
+ && !(flags &
+ (Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowCloseButtonHint))) {
+ // a special case - only the titlebar without any button
+ mwmhints.flags = MWM_HINTS_FUNCTIONS;
+ mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ mwmhints.decorations = 0;
+ }
+
+ if (widget()->windowModality() == Qt::WindowModal) {
+ mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
+ } else if (widget()->windowModality() == Qt::ApplicationModal) {
+ mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
+ }
+
+ setMWMHints(mwmhints);
+
+ QVector<Atom> netWmState = getNetWmState();
+
+ 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";
+ 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)))
+ netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_STAYS_ON_TOP));
+ } else if (flags & Qt::WindowStaysOnBottomHint) {
+ if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW)))
+ netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW));
+ }
+ if (widget()->isFullScreen()) {
+ if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN)))
+ netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN));
+ }
+ if (widget()->isMaximized()) {
+ 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 (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL)))
+ netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL));
+ }
+
+ if (!netWmState.isEmpty()) {
+ XChangeProperty(mScreen->display()->nativeDisplay(), x_window,
+ QXlibStatic::atom(QXlibStatic::_NET_WM_STATE), XA_ATOM, 32, PropModeReplace,
+ (unsigned char *) netWmState.data(), netWmState.size());
+ } else {
+ XDeleteProperty(mScreen->display()->nativeDisplay(), x_window, QXlibStatic::atom(QXlibStatic::_NET_WM_STATE));
+ }
+
+//##### only if initializeWindow???
+
+ if (popup || tooltip) { // popup widget
+#ifdef MYX11_DEBUG
+ qDebug() << "Doing XChangeWindowAttributes for popup" << wsa.override_redirect;
+#endif
+ // set EWMH window types
+ // setNetWmWindowTypes();
+
+ wsa.override_redirect = True;
+ wsa.save_under = True;
+ XChangeWindowAttributes(mScreen->display()->nativeDisplay(), x_window, CWOverrideRedirect | CWSaveUnder,
+ &wsa);
+ } else {
+#ifdef MYX11_DEBUG
+ qDebug() << "Doing XChangeWindowAttributes for non-popup";
+#endif
+ }
+
+ return flags;
+}
+
+void QXlibWindow::setVisible(bool visible)
+{
+#ifdef MYX11_DEBUG
+ qDebug() << "QTestLiteWindow::setVisible" << visible << hex << x_window;
+#endif
+ if (isTransient(widget())) {
+ 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;
+ }
+ }
+ XSetTransientForHint(mScreen->display()->nativeDisplay(),x_window,parentXWindow);
+ }
+
+ if (visible) {
+ //ensure that the window is viewed in correct position.
+ doSizeHints();
+ XMapWindow(mScreen->display()->nativeDisplay(), x_window);
+ } else {
+ XUnmapWindow(mScreen->display()->nativeDisplay(), x_window);
+ }
+}
+
+void QXlibWindow::setCursor(const Cursor &cursor)
+{
+ XDefineCursor(mScreen->display()->nativeDisplay(), x_window, cursor);
+ mScreen->display()->flush();
+}
+
+QPlatformGLContext *QXlibWindow::glContext() 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;
+}
+
+Window QXlibWindow::xWindow() const
+{
+ return x_window;
+}
+
+GC QXlibWindow::graphicsContext() const
+{
+ return gc;
+}
+
+void QXlibWindow::doSizeHints()
+{
+ Q_ASSERT(widget()->testAttribute(Qt::WA_WState_Created));
+ XSizeHints s;
+ s.flags = 0;
+ QRect g = geometry();
+ s.x = g.x();
+ s.y = g.y();
+ s.width = g.width();
+ s.height = g.height();
+ s.flags |= USPosition;
+ s.flags |= PPosition;
+ s.flags |= USSize;
+ s.flags |= PSize;
+ s.flags |= PWinGravity;
+ s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+ 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;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibwindow.h b/src/plugins/platforms/xlib/qxlibwindow.h
new file mode 100644
index 0000000000..08694a5026
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibwindow.h
@@ -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$
+** 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 QTESTLITEWINDOW_H
+#define QTESTLITEWINDOW_H
+
+#include "qxlibintegration.h"
+
+#include <QPlatformWindow>
+#include <QEvent>
+
+#include <QObject>
+#include <QImage>
+
+struct QXlibMWMHints {
+ ulong flags, functions, decorations;
+ long input_mode;
+ ulong status;
+};
+
+enum {
+ MWM_HINTS_FUNCTIONS = (1L << 0),
+
+ MWM_FUNC_ALL = (1L << 0),
+ MWM_FUNC_RESIZE = (1L << 1),
+ MWM_FUNC_MOVE = (1L << 2),
+ MWM_FUNC_MINIMIZE = (1L << 3),
+ MWM_FUNC_MAXIMIZE = (1L << 4),
+ MWM_FUNC_CLOSE = (1L << 5),
+
+ MWM_HINTS_DECORATIONS = (1L << 1),
+
+ MWM_DECOR_ALL = (1L << 0),
+ MWM_DECOR_BORDER = (1L << 1),
+ MWM_DECOR_RESIZEH = (1L << 2),
+ MWM_DECOR_TITLE = (1L << 3),
+ MWM_DECOR_MENU = (1L << 4),
+ MWM_DECOR_MINIMIZE = (1L << 5),
+ MWM_DECOR_MAXIMIZE = (1L << 6),
+
+ MWM_HINTS_INPUT_MODE = (1L << 2),
+
+ MWM_INPUT_MODELESS = 0L,
+ MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
+ MWM_INPUT_FULL_APPLICATION_MODAL = 3L
+};
+
+class QXlibWindow : public QPlatformWindow
+{
+public:
+ QXlibWindow(QWidget *window);
+ ~QXlibWindow();
+
+
+ void mousePressEvent(XButtonEvent*);
+ void handleMouseEvent(QEvent::Type, XButtonEvent *ev);
+
+ void handleCloseEvent();
+ void handleEnterEvent();
+ void handleLeaveEvent();
+ void handleFocusInEvent();
+ void handleFocusOutEvent();
+
+ void resizeEvent(XConfigureEvent *configure_event);
+ void paintEvent();
+
+ void requestActivateWindow();
+
+ void setGeometry(const QRect &rect);
+
+ Qt::WindowFlags setWindowFlags(Qt::WindowFlags type);
+ Qt::WindowFlags windowFlags() const;
+ void setVisible(bool visible);
+ WId winId() const;
+ void setParent(const QPlatformWindow *window);
+ void raise();
+ void lower();
+ void setWindowTitle(const QString &title);
+
+ void setCursor(const Cursor &cursor);
+
+ QPlatformGLContext *glContext() const;
+
+ Window xWindow() const;
+ GC graphicsContext() const;
+
+protected:
+ QVector<Atom> getNetWmState() const;
+ void setMWMHints(const QXlibMWMHints &mwmhints);
+ QXlibMWMHints getMWMHints() const;
+
+ void doSizeHints();
+
+private:
+ QPlatformWindowFormat correctColorBuffers(const QPlatformWindowFormat &windowFormat)const;
+
+ Window x_window;
+ GC gc;
+
+ GC createGC();
+
+ QPlatformGLContext *mGLContext;
+ QXlibScreen *mScreen;
+ Qt::WindowFlags mWindowFlags;
+};
+
+#endif
diff --git a/src/plugins/platforms/xlib/qxlibwindowsurface.cpp b/src/plugins/platforms/xlib/qxlibwindowsurface.cpp
new file mode 100644
index 0000000000..513f10dc6a
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibwindowsurface.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$
+** 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 "qxlibwindowsurface.h"
+#include "qxlibintegration.h"
+
+#include <QtCore/qdebug.h>
+#include <QWindowSystemInterface>
+
+#include "qxlibwindow.h"
+#include "qxlibscreen.h"
+#include "qxlibdisplay.h"
+
+# include <sys/ipc.h>
+# include <sys/shm.h>
+# include <X11/extensions/XShm.h>
+
+QT_BEGIN_NAMESPACE
+
+
+struct QXlibShmImageInfo {
+ QXlibShmImageInfo(Display *xdisplay) : image(0), display(xdisplay) {}
+ ~QXlibShmImageInfo() { destroy(); }
+
+ void destroy();
+
+ XShmSegmentInfo shminfo;
+ XImage *image;
+ Display *display;
+};
+
+
+#ifndef DONT_USE_MIT_SHM
+void QXlibShmImageInfo::destroy()
+{
+ XShmDetach (display, &shminfo);
+ XDestroyImage (image);
+ shmdt (shminfo.shmaddr);
+ shmctl (shminfo.shmid, IPC_RMID, 0);
+}
+#endif
+
+void QXlibWindowSurface::resizeShmImage(int width, int height)
+{
+
+#ifdef DONT_USE_MIT_SHM
+ shm_img = QImage(width, height, QImage::Format_RGB32);
+#else
+
+ QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
+ if (image_info)
+ image_info->destroy();
+ else
+ image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay());
+
+ Visual *visual = screen->defaultVisual();
+
+ XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), visual, 24, ZPixmap, 0,
+ &image_info->shminfo, width, height);
+
+
+ image_info->shminfo.shmid = shmget (IPC_PRIVATE,
+ image->bytes_per_line * image->height, IPC_CREAT|0777);
+
+ image_info->shminfo.shmaddr = image->data = (char*)shmat (image_info->shminfo.shmid, 0, 0);
+ image_info->shminfo.readOnly = False;
+
+ image_info->image = image;
+
+ Status shm_attach_status = XShmAttach(screen->display()->nativeDisplay(), &image_info->shminfo);
+
+ Q_ASSERT(shm_attach_status == True);
+
+ shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, QImage::Format_RGB32 );
+#endif
+ painted = false;
+}
+
+
+void QXlibWindowSurface::resizeBuffer(QSize s)
+{
+ if (shm_img.size() != s)
+ resizeShmImage(s.width(), s.height());
+}
+
+QSize QXlibWindowSurface::bufferSize() const
+{
+ return shm_img.size();
+}
+
+QXlibWindowSurface::QXlibWindowSurface (QWidget *window)
+ : QWindowSurface(window),
+ painted(false), image_info(0)
+{
+ xw = static_cast<QXlibWindow*>(window->platformWindow());
+// qDebug() << "QTestLiteWindowSurface::QTestLiteWindowSurface:" << xw->window;
+}
+
+QXlibWindowSurface::~QXlibWindowSurface()
+{
+ delete image_info;
+}
+
+QPaintDevice *QXlibWindowSurface::paintDevice()
+{
+ return &shm_img;
+}
+
+
+void QXlibWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+
+ if (!painted)
+ return;
+
+ QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(widget);
+ GC gc = xw->graphicsContext();
+ Window window = xw->xWindow();
+#ifdef DONT_USE_MIT_SHM
+ // just convert the image every time...
+ if (!shm_img.isNull()) {
+ Visual *visual = DefaultVisual(screen->display(), screen->xScreenNumber());
+
+ QImage image = shm_img;
+ //img.convertToFormat(
+ XImage *xi = XCreateImage(screen->display(), visual, 24, 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());
+
+ xi->data = 0; // QImage owns these bits
+ XDestroyImage(xi);
+ }
+#else
+ // Use MIT_SHM
+ if (image_info && image_info->image) {
+ //qDebug() << "Here we go" << image_info->image->width << image_info->image->height;
+ int x = 0;
+ int y = 0;
+
+ // We could set send_event to true, and then use the ShmCompletion to synchronize,
+ // but let's do like Qt/11 and just use XSync
+ XShmPutImage (screen->display()->nativeDisplay(), window, gc, image_info->image, 0, 0,
+ x, y, image_info->image->width, image_info->image->height,
+ /*send_event*/ False);
+
+ screen->display()->sync();
+ }
+#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)
+{
+ 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;
+}
+
+
+void QXlibWindowSurface::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+ resizeBuffer(size());
+}
+
+void QXlibWindowSurface::endPaint(const QRegion &region)
+{
+ 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/qxlibwindowsurface.h
new file mode 100644
index 0000000000..d46b7b41bc
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibwindowsurface.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$
+** 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 QWINDOWSURFACE_TESTLITE_H
+#define QWINDOWSURFACE_TESTLITE_H
+
+#include <QtGui/private/qwindowsurface_p.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class QXlibWindow;
+class QXlibIntegration;
+class QXlibScreen;
+class QXlibShmImageInfo;
+
+class QXlibWindowSurface : public QWindowSurface
+{
+public:
+ QXlibWindowSurface (QWidget *window);
+ ~QXlibWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ bool scroll(const QRegion &area, int dx, int dy);
+
+ void beginPaint(const QRegion &region);
+ void endPaint(const QRegion &region);
+
+private:
+ bool painted;
+ void resizeBuffer(QSize);
+ QSize bufferSize() const;
+
+
+ void resizeShmImage(int width, int height);
+
+ QImage shm_img;
+ QXlibShmImageInfo *image_info;
+
+ QXlibWindow *xw;
+
+};
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xlib/xlib.pro b/src/plugins/platforms/xlib/xlib.pro
new file mode 100644
index 0000000000..ea77a2905b
--- /dev/null
+++ b/src/plugins/platforms/xlib/xlib.pro
@@ -0,0 +1,62 @@
+TARGET = qxlib
+
+include(../../qpluginbase.pri)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+SOURCES = \
+ main.cpp \
+ qxlibintegration.cpp \
+ qxlibwindowsurface.cpp \
+ qxlibwindow.cpp \
+ qxlibcursor.cpp \
+ qxlibscreen.cpp \
+ qxlibkeyboard.cpp \
+ qxlibclipboard.cpp \
+ qxlibmime.cpp \
+ qxlibstatic.cpp \
+ qxlibdisplay.cpp \
+ qxlibnativeinterface.cpp
+
+HEADERS = \
+ qxlibintegration.h \
+ qxlibwindowsurface.h \
+ qxlibwindow.h \
+ qxlibcursor.h \
+ qxlibscreen.h \
+ qxlibkeyboard.h \
+ qxlibclipboard.h \
+ qxlibmime.h \
+ qxlibstatic.h \
+ qxlibdisplay.h \
+ qxlibnativeinterface.h
+
+LIBS += -lX11 -lXext
+
+mac {
+ LIBS += -L/usr/X11/lib -lz -framework Carbon
+}
+
+include (../fontdatabases/genericunix/genericunix.pri)
+
+contains(QT_CONFIG, opengl) {
+ QT += opengl
+ !contains(QT_CONFIG, opengles2) {
+ include (../glxconvenience/glxconvenience.pri)
+ 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
+ LIBS += -lEGL
+ }
+}
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target