summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-myanmar.c4
-rw-r--r--src/3rdparty/phonon/phonon/mediacontroller.cpp4
-rw-r--r--src/3rdparty/phonon/phonon/qsettingsgroup_p.h4
-rw-r--r--src/3rdparty/phonon/qt7/videowidget.mm2
-rw-r--r--src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp12
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp2
-rw-r--r--src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp28
-rw-r--r--src/activeqt/container/qaxbase.cpp12
-rw-r--r--src/activeqt/container/qaxwidget.cpp4
-rw-r--r--src/activeqt/control/qaxserver.cpp2
-rw-r--r--src/activeqt/control/qaxserverbase.cpp16
-rw-r--r--src/activeqt/shared/qaxtypes.cpp28
-rw-r--r--src/corelib/concurrent/qfuture.h2
-rw-r--r--src/corelib/concurrent/qfuturewatcher.cpp9
-rw-r--r--src/corelib/concurrent/qtconcurrentcompilertest.h6
-rw-r--r--src/corelib/concurrent/qtconcurrentiteratekernel.h5
-rw-r--r--src/corelib/concurrent/qthreadpool.cpp34
-rw-r--r--src/corelib/concurrent/qthreadpool.h1
-rw-r--r--src/corelib/concurrent/qthreadpool_p.h2
-rw-r--r--src/corelib/global/qendian.h4
-rw-r--r--src/corelib/global/qglobal.cpp5
-rw-r--r--src/corelib/global/qglobal.h131
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/global/qnamespace.qdoc5
-rw-r--r--src/corelib/io/qabstractfileengine.cpp54
-rw-r--r--src/corelib/io/qdatastream.h7
-rw-r--r--src/corelib/io/qdebug.h7
-rw-r--r--src/corelib/io/qdir.cpp5
-rw-r--r--src/corelib/io/qdir.h4
-rw-r--r--src/corelib/io/qfileinfo.h4
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp3
-rw-r--r--src/corelib/io/qfsfileengine.cpp14
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp6
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp38
-rw-r--r--src/corelib/io/qiodevice.cpp12
-rw-r--r--src/corelib/io/qresource.cpp23
-rw-r--r--src/corelib/io/qsettings.cpp4
-rw-r--r--src/corelib/io/qurl.cpp360
-rw-r--r--src/corelib/io/qurl.h5
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp2
-rw-r--r--src/corelib/kernel/qcore_symbian_p.cpp6
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp40
-rw-r--r--src/corelib/kernel/qcoreapplication.h18
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h6
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp3
-rw-r--r--src/corelib/kernel/qmetaobject.cpp73
-rw-r--r--src/corelib/kernel/qmetaobject.h2
-rw-r--r--src/corelib/kernel/qmetaobject_p.h2
-rw-r--r--src/corelib/kernel/qmetatype.cpp1
-rw-r--r--src/corelib/kernel/qmetatype.h1
-rw-r--r--src/corelib/kernel/qobject.cpp615
-rw-r--r--src/corelib/kernel/qobject.h105
-rw-r--r--src/corelib/kernel/qobject_p.h8
-rw-r--r--src/corelib/kernel/qobjectdefs.h5
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp126
-rw-r--r--src/corelib/kernel/qsharedmemory.h2
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h1
-rw-r--r--src/corelib/kernel/qsharedmemory_symbian.cpp11
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp15
-rw-r--r--src/corelib/kernel/qsharedmemory_win.cpp13
-rw-r--r--src/corelib/kernel/qvariant.cpp72
-rw-r--r--src/corelib/kernel/qvariant.h34
-rw-r--r--src/corelib/plugin/plugin.pri6
-rw-r--r--src/corelib/plugin/qelfparser_p.cpp234
-rw-r--r--src/corelib/plugin/qelfparser_p.h103
-rw-r--r--src/corelib/plugin/qlibrary.cpp213
-rw-r--r--src/corelib/plugin/qlibrary_p.h2
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp12
-rw-r--r--src/corelib/plugin/qplugin.h13
-rw-r--r--src/corelib/plugin/qpluginloader.cpp8
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp10
-rw-r--r--src/corelib/thread/qmutex.cpp139
-rw-r--r--src/corelib/thread/qmutex.h71
-rw-r--r--src/corelib/thread/qmutex_p.h11
-rw-r--r--src/corelib/thread/qmutex_unix.cpp2
-rw-r--r--src/corelib/thread/qmutex_win.cpp2
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h14
-rw-r--r--src/corelib/thread/qthreadstorage.h4
-rw-r--r--src/corelib/tools/qbitarray.h4
-rw-r--r--src/corelib/tools/qbytearray.cpp12
-rw-r--r--src/corelib/tools/qbytearray.h4
-rw-r--r--src/corelib/tools/qcache.h2
-rw-r--r--src/corelib/tools/qcontiguouscache.h4
-rw-r--r--src/corelib/tools/qelapsedtimer.cpp23
-rw-r--r--src/corelib/tools/qelapsedtimer.h3
-rw-r--r--src/corelib/tools/qelapsedtimer_win.cpp52
-rw-r--r--src/corelib/tools/qhash.h9
-rw-r--r--src/corelib/tools/qlinkedlist.h4
-rw-r--r--src/corelib/tools/qlist.h17
-rw-r--r--src/corelib/tools/qmap.h10
-rw-r--r--src/corelib/tools/qregexp.cpp3
-rw-r--r--src/corelib/tools/qregexp.h4
-rw-r--r--src/corelib/tools/qscopedpointer.h24
-rw-r--r--src/corelib/tools/qset.h4
-rw-r--r--src/corelib/tools/qshareddata.h10
-rw-r--r--src/corelib/tools/qsharedpointer.cpp4
-rw-r--r--src/corelib/tools/qsharedpointer.h3
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h24
-rw-r--r--src/corelib/tools/qstring.cpp1037
-rw-r--r--src/corelib/tools/qstring.h66
-rw-r--r--src/corelib/tools/qvector.h30
-rw-r--r--src/dbus/qdbusabstractinterface.cpp2
-rw-r--r--src/dbus/qdbusdemarshaller.cpp18
-rw-r--r--src/dbus/qdbusintegrator.cpp4
-rw-r--r--src/dbus/qdbusinternalfilters.cpp6
-rw-r--r--src/declarative/debugger/qdeclarativedebug.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp67
-rw-r--r--src/declarative/qml/parser/qdeclarativejsengine_p.h6
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp32
-rw-r--r--src/declarative/qml/qdeclarativesqldatabase.cpp8
-rw-r--r--src/declarative/qml/qdeclarativestringconverters.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp2
-rw-r--r--src/declarative/qml/qdeclarativexmlhttprequest.cpp23
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp4
-rw-r--r--src/declarative/util/qdeclarativeanimation_p.h2
-rw-r--r--src/declarative/util/qdeclarativeanimation_p_p.h3
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp6
-rw-r--r--src/declarative/util/qdeclarativeview.cpp17
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp2
-rw-r--r--src/gui/accessible/qaccessible.cpp17
-rw-r--r--src/gui/accessible/qaccessibleobject.cpp2
-rw-r--r--src/gui/accessible/qaccessiblewidget.cpp2
-rw-r--r--src/gui/dialogs/qdialog.cpp6
-rw-r--r--src/gui/dialogs/qfiledialog.cpp2
-rw-r--r--src/gui/dialogs/qfilesystemmodel.cpp12
-rw-r--r--src/gui/dialogs/qfilesystemmodel.h4
-rw-r--r--src/gui/dialogs/qmessagebox.cpp6
-rw-r--r--src/gui/dialogs/qnspanelproxy_mac.mm87
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.cpp12
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.h3
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp48
-rw-r--r--src/gui/graphicsview/qgraphicsitemanimation.cpp22
-rw-r--r--src/gui/graphicsview/qgraphicslayout.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicslayout_p.cpp12
-rw-r--r--src/gui/graphicsview/qgraphicslayout_p.h8
-rw-r--r--src/gui/graphicsview/qgraphicslayoutitem.cpp7
-rw-r--r--src/gui/graphicsview/qgraphicslayoutitem.h2
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp8
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h34
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp38
-rw-r--r--src/gui/graphicsview/qgridlayoutengine.cpp9
-rw-r--r--src/gui/graphicsview/qgridlayoutengine_p.h1
-rw-r--r--src/gui/image/qicon.h4
-rw-r--r--src/gui/image/qimage.cpp82
-rw-r--r--src/gui/image/qimage.h8
-rw-r--r--src/gui/image/qimagereader.cpp2
-rw-r--r--src/gui/image/qmnghandler.cpp2
-rw-r--r--src/gui/image/qpicture.h4
-rw-r--r--src/gui/image/qpixmap.cpp2
-rw-r--r--src/gui/image/qpixmap.h4
-rw-r--r--src/gui/image/qpixmap_x11.cpp12
-rw-r--r--src/gui/image/qtiffhandler.cpp7
-rw-r--r--src/gui/itemviews/qabstractitemdelegate.cpp4
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp143
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h35
-rw-r--r--src/gui/itemviews/qabstractproxymodel.cpp96
-rw-r--r--src/gui/itemviews/qabstractproxymodel.h12
-rw-r--r--src/gui/itemviews/qheaderview.cpp8
-rw-r--r--src/gui/itemviews/qitemdelegate.cpp10
-rw-r--r--src/gui/itemviews/qitemselectionmodel.cpp21
-rw-r--r--src/gui/itemviews/qitemselectionmodel.h24
-rw-r--r--src/gui/itemviews/qlistview.cpp119
-rw-r--r--src/gui/itemviews/qlistview_p.h9
-rw-r--r--src/gui/itemviews/qstyleditemdelegate.cpp9
-rw-r--r--src/gui/itemviews/qtableview.cpp13
-rw-r--r--src/gui/itemviews/qtreeview.cpp37
-rw-r--r--src/gui/kernel/kernel.pri6
-rw-r--r--src/gui/kernel/qapplication.cpp49
-rw-r--r--src/gui/kernel/qapplication.h12
-rw-r--r--src/gui/kernel/qapplication_mac.mm29
-rw-r--r--src/gui/kernel/qapplication_p.h4
-rw-r--r--src/gui/kernel/qapplication_s60.cpp4
-rw-r--r--src/gui/kernel/qapplication_win.cpp39
-rw-r--r--src/gui/kernel/qapplication_x11.cpp31
-rw-r--r--src/gui/kernel/qclipboard.cpp2
-rw-r--r--src/gui/kernel/qcocoaapplication_mac.mm76
-rw-r--r--src/gui/kernel/qcocoaapplication_mac_p.h8
-rw-r--r--src/gui/kernel/qcocoaintrospection_mac.mm125
-rw-r--r--src/gui/kernel/qcocoaintrospection_p.h84
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h11
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm35
-rw-r--r--src/gui/kernel/qcocoaview_mac_p.h1
-rw-r--r--src/gui/kernel/qcursor.h4
-rw-r--r--src/gui/kernel/qdesktopwidget_win.cpp14
-rw-r--r--src/gui/kernel/qevent.cpp2
-rw-r--r--src/gui/kernel/qguifunctions_wince.cpp2
-rw-r--r--src/gui/kernel/qkeysequence.cpp7
-rw-r--r--src/gui/kernel/qkeysequence.h4
-rw-r--r--src/gui/kernel/qlayoutitem.cpp4
-rw-r--r--src/gui/kernel/qmacdefines_mac.h12
-rw-r--r--src/gui/kernel/qpalette.h8
-rw-r--r--src/gui/kernel/qsizepolicy.h21
-rw-r--r--src/gui/kernel/qsizepolicy.qdoc24
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm201
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h12
-rw-r--r--src/gui/kernel/qtooltip.cpp2
-rw-r--r--src/gui/kernel/qwidget.cpp34
-rw-r--r--src/gui/kernel/qwidget.h8
-rw-r--r--src/gui/kernel/qwidget_mac.mm36
-rw-r--r--src/gui/kernel/qwidget_p.h1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp8
-rw-r--r--src/gui/kernel/qwidget_win.cpp5
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp14
-rw-r--r--src/gui/math3d/qmatrix4x4.h16
-rw-r--r--src/gui/painting/qbrush.h4
-rw-r--r--src/gui/painting/qoutlinemapper.cpp9
-rw-r--r--src/gui/painting/qoutlinemapper_p.h8
-rw-r--r--src/gui/painting/qpaintbuffer.cpp44
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp74
-rw-r--r--src/gui/painting/qpainter.cpp164
-rw-r--r--src/gui/painting/qpainter.h5
-rw-r--r--src/gui/painting/qpainter_p.h3
-rw-r--r--src/gui/painting/qpainterpath.h4
-rw-r--r--src/gui/painting/qpen.h4
-rw-r--r--src/gui/painting/qrasterizer.cpp6
-rw-r--r--src/gui/painting/qregion.h5
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp142
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h44
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp19
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp3
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp1
-rw-r--r--src/gui/styles/qmacstyle_mac.mm53
-rw-r--r--src/gui/styles/qplastiquestyle.cpp2
-rw-r--r--src/gui/styles/qs60style.cpp2
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp19
-rw-r--r--src/gui/styles/qwindowscestyle.cpp1
-rw-r--r--src/gui/styles/qwindowsstyle.cpp6
-rw-r--r--src/gui/styles/qwindowsvistastyle.cpp12
-rw-r--r--src/gui/styles/qwindowsxpstyle.cpp2
-rw-r--r--src/gui/symbian/qsymbianevent.cpp33
-rw-r--r--src/gui/symbian/qsymbianevent.h4
-rw-r--r--src/gui/text/qcssparser.cpp46
-rw-r--r--src/gui/text/qcssparser_p.h2
-rw-r--r--src/gui/text/qfont.h6
-rw-r--r--src/gui/text/qfont_p.h5
-rw-r--r--src/gui/text/qfontdatabase.cpp4
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp118
-rw-r--r--src/gui/text/qfontengine.cpp32
-rw-r--r--src/gui/text/qfontengine_ft.cpp15
-rw-r--r--src/gui/text/qfontengine_ft_p.h2
-rw-r--r--src/gui/text/qfontengine_mac.mm55
-rw-r--r--src/gui/text/qfontengine_p.h24
-rw-r--r--src/gui/text/qfontengine_s60.cpp7
-rw-r--r--src/gui/text/qfontengine_win.cpp2
-rw-r--r--src/gui/text/qfontengine_win_p.h2
-rw-r--r--src/gui/text/qfontengine_x11.cpp2
-rw-r--r--src/gui/text/qfontengineglyphcache_p.h2
-rw-r--r--src/gui/text/qfontmetrics.cpp32
-rw-r--r--src/gui/text/qfontmetrics.h11
-rw-r--r--src/gui/text/qglyphs.cpp240
-rw-r--r--src/gui/text/qglyphs.h96
-rw-r--r--src/gui/text/qglyphs_p.h84
-rw-r--r--src/gui/text/qpfutil.cpp2
-rw-r--r--src/gui/text/qtextcontrol.cpp2
-rw-r--r--src/gui/text/qtextdocument.cpp36
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp4
-rw-r--r--src/gui/text/qtextengine.cpp82
-rw-r--r--src/gui/text/qtextengine_p.h23
-rw-r--r--src/gui/text/qtextformat.cpp44
-rw-r--r--src/gui/text/qtextformat.h16
-rw-r--r--src/gui/text/qtexthtmlparser.cpp6
-rw-r--r--src/gui/text/qtexthtmlparser_p.h2
-rw-r--r--src/gui/text/qtextlayout.cpp456
-rw-r--r--src/gui/text/qtextlayout.h6
-rw-r--r--src/gui/text/qtextlist.cpp14
-rw-r--r--src/gui/text/qtextobject.cpp29
-rw-r--r--src/gui/text/qtextobject.h3
-rw-r--r--src/gui/text/qtextodfwriter.cpp10
-rw-r--r--src/gui/text/text.pri7
-rw-r--r--src/gui/widgets/qabstractbutton.cpp2
-rw-r--r--src/gui/widgets/qcheckbox.cpp9
-rw-r--r--src/gui/widgets/qcheckbox.h1
-rw-r--r--src/gui/widgets/qcombobox.cpp20
-rw-r--r--src/gui/widgets/qcombobox.h2
-rw-r--r--src/gui/widgets/qcombobox_p.h2
-rw-r--r--src/gui/widgets/qdatetimeedit.cpp15
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp2
-rw-r--r--src/gui/widgets/qlabel.cpp2
-rw-r--r--src/gui/widgets/qlineedit.h1
-rw-r--r--src/gui/widgets/qlineedit_p.cpp23
-rw-r--r--src/gui/widgets/qlineedit_p.h3
-rw-r--r--src/gui/widgets/qmainwindow.cpp4
-rw-r--r--src/gui/widgets/qmdisubwindow.cpp4
-rw-r--r--src/gui/widgets/qmenu.cpp2
-rw-r--r--src/gui/widgets/qmenu_mac.mm17
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp3
-rw-r--r--src/gui/widgets/qmenu_wince.cpp2
-rw-r--r--src/gui/widgets/qradiobutton.cpp8
-rw-r--r--src/gui/widgets/qradiobutton.h1
-rw-r--r--src/gui/widgets/qsizegrip.cpp17
-rw-r--r--src/gui/widgets/qspinbox.cpp3
-rw-r--r--src/gui/widgets/qsplashscreen.cpp54
-rw-r--r--src/gui/widgets/qstackedwidget.cpp46
-rw-r--r--src/gui/widgets/qtabbar.cpp13
-rw-r--r--src/gui/widgets/qtabwidget.cpp62
-rw-r--r--src/gui/widgets/qtabwidget.h1
-rw-r--r--src/gui/widgets/qtoolbutton.cpp3
-rw-r--r--src/gui/widgets/qworkspace.cpp2
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp6
-rw-r--r--src/multimedia/video/qvideosurfaceformat.cpp26
-rw-r--r--src/network/access/qfilenetworkreply.cpp9
-rw-r--r--src/network/access/qfilenetworkreply_p.h2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp13
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp188
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h13
-rw-r--r--src/network/access/qhttpnetworkreply.cpp113
-rw-r--r--src/network/access/qhttpnetworkreply_p.h15
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp11
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h4
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp13
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h4
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp11
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp2
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp33
-rw-r--r--src/network/access/qnetworkaccesshttpbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp15
-rw-r--r--src/network/access/qnetworkreply.cpp18
-rw-r--r--src/network/access/qnetworkreply.h1
-rw-r--r--src/network/access/qnetworkreply_p.h3
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp106
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h12
-rw-r--r--src/network/access/qnetworkrequest.cpp4
-rw-r--r--src/network/kernel/qhostinfo.cpp26
-rw-r--r--src/network/kernel/qhostinfo_p.h7
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp2
-rw-r--r--src/network/kernel/qhostinfo_win.cpp7
-rw-r--r--src/network/socket/qabstractsocket.cpp183
-rw-r--r--src/network/socket/qabstractsocket.h4
-rw-r--r--src/network/socket/qabstractsocket_p.h3
-rw-r--r--src/network/socket/qabstractsocketengine_p.h12
-rw-r--r--src/network/socket/qhttpsocketengine.cpp29
-rw-r--r--src/network/socket/qhttpsocketengine_p.h7
-rw-r--r--src/network/socket/qnativesocketengine.cpp46
-rw-r--r--src/network/socket/qnativesocketengine_p.h14
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp216
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp221
-rw-r--r--src/network/socket/qsocks5socketengine.cpp30
-rw-r--r--src/network/socket/qsocks5socketengine_p.h7
-rw-r--r--src/network/socket/qudpsocket.cpp122
-rw-r--r--src/network/socket/qudpsocket.h11
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp64
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h11
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp35
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache_p.h9
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp15
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp92
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h95
-rw-r--r--src/opengl/opengl.pro4
-rw-r--r--src/opengl/qgl.cpp197
-rw-r--r--src/opengl/qgl.h6
-rw-r--r--src/opengl/qgl_p.h164
-rw-r--r--src/opengl/qgl_win.cpp5
-rw-r--r--src/opengl/qgl_x11egl.cpp3
-rw-r--r--src/opengl/qglextensions_p.h4
-rw-r--r--src/opengl/qglframebufferobject.cpp15
-rw-r--r--src/opengl/qglfunctions.cpp3705
-rw-r--r--src/opengl/qglfunctions.h2290
-rw-r--r--src/opengl/qglpixelbuffer.cpp20
-rw-r--r--src/opengl/qglpixelbuffer_win.cpp8
-rw-r--r--src/opengl/qglpixmapfilter.cpp19
-rw-r--r--src/openvg/qvg_symbian.cpp9
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp2
-rw-r--r--src/plugins/accessible/widgets/rangecontrols.cpp4
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp2
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux.cpp8
-rw-r--r--src/plugins/gfxdrivers/eglnullws/README48
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullws.pro18
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp181
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h69
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp66
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h47
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp84
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h63
-rw-r--r--src/plugins/gfxdrivers/gfxdrivers.pro1
-rw-r--r--src/plugins/qpluginbase.pri2
-rw-r--r--src/qbase.pri2
-rw-r--r--src/qt3support/text/q3richtext.cpp4
-rw-r--r--src/qt3support/text/q3textstream.h6
-rw-r--r--src/qt3support/tools/q3cstring.h50
-rw-r--r--src/s60main/qts60main.cpp3
-rw-r--r--src/script/api/qscriptengine.cpp52
-rw-r--r--src/script/api/qscriptengine.h67
-rw-r--r--src/script/api/qscriptvalue.cpp12
-rw-r--r--src/script/bridge/qscriptclassobject.cpp6
-rw-r--r--src/script/bridge/qscriptqobject.cpp10
-rw-r--r--src/scripttools/debugging/qscriptdebuggercommand.cpp6
-rw-r--r--src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp8
-rw-r--r--src/scripttools/debugging/qscriptdebuggerconsole.cpp14
-rw-r--r--src/scripttools/debugging/qscriptdebuggerevent.cpp2
-rw-r--r--src/scripttools/debugging/qscriptdebuggerresponse.cpp16
-rw-r--r--src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp2
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp6
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp14
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp37
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp4
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp4
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.cpp4
-rw-r--r--src/sql/kernel/qsqldatabase.cpp8
-rw-r--r--src/testlib/qabstracttestlogger_p.h2
-rw-r--r--src/testlib/qplaintestlogger.cpp22
-rw-r--r--src/testlib/qplaintestlogger_p.h4
-rw-r--r--src/testlib/qtest.h2
-rw-r--r--src/testlib/qtest_global.h2
-rw-r--r--src/testlib/qtestcase.cpp159
-rw-r--r--src/testlib/qtestlightxmlstreamer.cpp8
-rw-r--r--src/testlib/qtestlog.cpp55
-rw-r--r--src/testlib/qtestlog_p.h2
-rw-r--r--src/testlib/qtestlogger.cpp27
-rw-r--r--src/testlib/qtestlogger_p.h5
-rw-r--r--src/testlib/qtestresult.cpp5
-rw-r--r--src/testlib/qtestxmlstreamer.cpp10
-rw-r--r--src/testlib/qxmltestlogger.cpp27
-rw-r--r--src/testlib/qxmltestlogger_p.h4
-rw-r--r--src/tools/bootstrap/bootstrap.pri4
-rw-r--r--src/tools/bootstrap/bootstrap.pro4
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp90
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.h1
-rw-r--r--src/tools/uic/ui4.cpp11
-rw-r--r--src/tools/uic/ui4.h8
-rw-r--r--src/tools/uic3/converter.cpp2
-rw-r--r--src/tools/uic3/domtool.cpp14
-rw-r--r--src/tools/uic3/domtool.h2
-rw-r--r--src/xmlpatterns/api/quriloader.cpp2
-rw-r--r--src/xmlpatterns/api/qvariableloader.cpp14
-rw-r--r--src/xmlpatterns/api/qxmlquery.cpp6
-rw-r--r--src/xmlpatterns/data/qatomicvalue.cpp2
-rw-r--r--src/xmlpatterns/utils/qautoptr_p.h2
429 files changed, 15353 insertions, 3352 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-myanmar.c b/src/3rdparty/harfbuzz/src/harfbuzz-myanmar.c
index 7cd82bb1e6..4b68e64d85 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-myanmar.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-myanmar.c
@@ -424,12 +424,8 @@ static HB_Bool myanmar_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_
#ifndef NO_OPENTYPE
if (openType) {
- unsigned short logClusters[32];
hb_uint32 where[32];
- for (i = 0; i < len; ++i)
- logClusters[i] = i;
-
for (i = 0; i < len; ++i) {
where[i] = ~(PreSubstProperty
| BelowSubstProperty
diff --git a/src/3rdparty/phonon/phonon/mediacontroller.cpp b/src/3rdparty/phonon/phonon/mediacontroller.cpp
index 59fd5c7dfd..9f651d64dc 100644
--- a/src/3rdparty/phonon/phonon/mediacontroller.cpp
+++ b/src/3rdparty/phonon/phonon/mediacontroller.cpp
@@ -216,14 +216,14 @@ void MediaController::setCurrentAudioChannel(const Phonon::AudioChannelDescripti
{
IFACE;
iface->interfaceCall(AddonInterface::AudioChannelInterface,
- AddonInterface::setCurrentAudioChannel, QList<QVariant>() << qVariantFromValue(stream));
+ AddonInterface::setCurrentAudioChannel, QList<QVariant>() << QVariant::fromValue(stream));
}
void MediaController::setCurrentSubtitle(const Phonon::SubtitleDescription &stream)
{
IFACE;
iface->interfaceCall(AddonInterface::SubtitleInterface,
- AddonInterface::setCurrentSubtitle, QList<QVariant>() << qVariantFromValue(stream));
+ AddonInterface::setCurrentSubtitle, QList<QVariant>() << QVariant::fromValue(stream));
}
#undef IFACE
diff --git a/src/3rdparty/phonon/phonon/qsettingsgroup_p.h b/src/3rdparty/phonon/phonon/qsettingsgroup_p.h
index f28ecaa267..f25b15e745 100644
--- a/src/3rdparty/phonon/phonon/qsettingsgroup_p.h
+++ b/src/3rdparty/phonon/phonon/qsettingsgroup_p.h
@@ -54,7 +54,7 @@ class QSettingsGroup
template<typename T>
inline T value(const QString &key, const T &def) const
{
- return qvariant_cast<T>(value(key, qVariantFromValue(def)));
+ return qvariant_cast<T>(value(key, QVariant::fromValue(def)));
}
inline QVariant value(const QString &key, const QVariant &def) const
@@ -66,7 +66,7 @@ class QSettingsGroup
inline void setValue(const QString &key, const T &value)
{
Q_ASSERT(m_mutableSettings);
- m_mutableSettings->setValue(m_group + key, qVariantFromValue(value));
+ m_mutableSettings->setValue(m_group + key, QVariant::fromValue(value));
}
inline void removeEntry(const QString &key)
diff --git a/src/3rdparty/phonon/qt7/videowidget.mm b/src/3rdparty/phonon/qt7/videowidget.mm
index 736dcdf846..c281e1622f 100644
--- a/src/3rdparty/phonon/qt7/videowidget.mm
+++ b/src/3rdparty/phonon/qt7/videowidget.mm
@@ -278,7 +278,7 @@ public:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, GLsizei(w), GLsizei(h));
- gluOrtho2D(0, GLsizei(w), 0, GLsizei(h));
+ glOrtho(0, GLsizei(w), 0, GLsizei(h), -1, 1);
updateGL();
}
diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp
index 2212f58c5f..7f5d37d585 100644
--- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp
+++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp
@@ -567,7 +567,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
if (qstring.mid(lastSlash + 1).contains(QLatin1Char('i')))
realRe.setCaseSensitivity(Qt::CaseInsensitive);
- ret = qVariantFromValue(realRe);
+ ret = QVariant::fromValue(realRe);
dist = 0;
} else {
qConvDebug() << "couldn't parse a JS regexp";
@@ -578,7 +578,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
QRegExp re(qstring);
if (re.isValid()) {
- ret = qVariantFromValue(re);
+ ret = QVariant::fromValue(re);
dist = 10;
}
}
@@ -590,7 +590,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
if (qtinst) {
if (qtinst->getObject()) {
qConvDebug() << "found instance, with object:" << (void*) qtinst->getObject();
- ret = qVariantFromValue(qtinst->getObject());
+ ret = QVariant::fromValue(qtinst->getObject());
qConvDebug() << ret;
dist = 0;
} else {
@@ -601,7 +601,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
}
} else if (type == Null) {
QObject* nullobj = 0;
- ret = qVariantFromValue(nullobj);
+ ret = QVariant::fromValue(nullobj);
dist = 0;
} else {
qConvDebug() << "previous type was not an object:" << type;
@@ -614,7 +614,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
if (qtinst) {
if (qtinst->getObject()) {
qConvDebug() << "found instance, with object:" << (void*) qtinst->getObject();
- ret = qVariantFromValue((void *)qtinst->getObject());
+ ret = QVariant::fromValue((void *)qtinst->getObject());
qConvDebug() << ret;
dist = 0;
} else {
@@ -624,7 +624,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
qConvDebug() << "wasn't a qtinstance";
}
} else if (type == Null) {
- ret = qVariantFromValue((void*)0);
+ ret = QVariant::fromValue((void*)0);
dist = 0;
} else if (type == Number) {
// I don't think that converting a double to a pointer is a wise
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
index 88c7a1c274..9de5c08222 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
@@ -101,7 +101,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
// Make sure we get updates for each frame
m_videoWidget->installEventFilter(this);
- foreach (QWidget* widget, qFindChildren<QWidget*>(m_videoWidget))
+ foreach (QWidget* widget, m_videoWidget->findChildren<QWidget*>())
widget->installEventFilter(this);
connect(m_mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index 5db94a88a0..5004b67ccb 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -185,7 +185,7 @@ void MediaPlayerPrivate::load(const String& url)
// Don't set the header if there are no cookies.
// This prevents a warning from being emitted.
if (!cookies.isEmpty())
- request.setHeader(QNetworkRequest::CookieHeader, qVariantFromValue(cookies));
+ request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));
// Set the refferer, but not when requesting insecure content from a secure page
QUrl documentUrl = QUrl(QString(document->documentURI()));
diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
index e584f97f6f..dcae35f06c 100644
--- a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
@@ -306,7 +306,7 @@ public:
}
Q_INVOKABLE QObjectList myInvokableWithQObjectListArg(const QObjectList &lst) {
m_qtFunctionInvoked = 14;
- m_actuals << qVariantFromValue(lst);
+ m_actuals << QVariant::fromValue(lst);
return lst;
}
Q_INVOKABLE QVariant myInvokableWithVariantArg(const QVariant &v) {
@@ -321,38 +321,38 @@ public:
}
Q_INVOKABLE QList<int> myInvokableWithListOfIntArg(const QList<int> &lst) {
m_qtFunctionInvoked = 17;
- m_actuals << qVariantFromValue(lst);
+ m_actuals << QVariant::fromValue(lst);
return lst;
}
Q_INVOKABLE QObject* myInvokableWithQObjectStarArg(QObject* obj) {
m_qtFunctionInvoked = 18;
- m_actuals << qVariantFromValue(obj);
+ m_actuals << QVariant::fromValue(obj);
return obj;
}
Q_INVOKABLE QBrush myInvokableWithQBrushArg(const QBrush &brush) {
m_qtFunctionInvoked = 19;
- m_actuals << qVariantFromValue(brush);
+ m_actuals << QVariant::fromValue(brush);
return brush;
}
Q_INVOKABLE void myInvokableWithBrushStyleArg(Qt::BrushStyle style) {
m_qtFunctionInvoked = 43;
- m_actuals << qVariantFromValue(style);
+ m_actuals << QVariant::fromValue(style);
}
Q_INVOKABLE void myInvokableWithVoidStarArg(void* arg) {
m_qtFunctionInvoked = 44;
- m_actuals << qVariantFromValue(arg);
+ m_actuals << QVariant::fromValue(arg);
}
Q_INVOKABLE void myInvokableWithAmbiguousArg(int arg) {
m_qtFunctionInvoked = 45;
- m_actuals << qVariantFromValue(arg);
+ m_actuals << QVariant::fromValue(arg);
}
Q_INVOKABLE void myInvokableWithAmbiguousArg(uint arg) {
m_qtFunctionInvoked = 46;
- m_actuals << qVariantFromValue(arg);
+ m_actuals << QVariant::fromValue(arg);
}
Q_INVOKABLE void myInvokableWithDefaultArgs(int arg1, const QString &arg2 = "") {
m_qtFunctionInvoked = 47;
- m_actuals << qVariantFromValue(arg1) << qVariantFromValue(arg2);
+ m_actuals << QVariant::fromValue(arg1) << qVariantFromValue(arg2);
}
Q_INVOKABLE QObject& myInvokableReturningRef() {
m_qtFunctionInvoked = 48;
@@ -364,11 +364,11 @@ public:
}
Q_INVOKABLE void myInvokableWithPointArg(const QPoint &arg) {
const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 50;
- m_actuals << qVariantFromValue(arg);
+ m_actuals << QVariant::fromValue(arg);
}
Q_INVOKABLE void myInvokableWithPointArg(const QPointF &arg) {
const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 51;
- m_actuals << qVariantFromValue(arg);
+ m_actuals << QVariant::fromValue(arg);
}
Q_INVOKABLE void myInvokableWithBoolArg(bool arg) {
m_qtFunctionInvoked = 52;
@@ -416,7 +416,7 @@ public Q_SLOTS:
}
void myOverloadedSlot(QObject* arg) {
m_qtFunctionInvoked = 41;
- m_actuals << qVariantFromValue(arg);
+ m_actuals << QVariant::fromValue(arg);
}
void myOverloadedSlot(bool arg) {
m_qtFunctionInvoked = 25;
@@ -818,7 +818,7 @@ void tst_QWebFrame::getSetStaticProperty()
QCOMPARE(evalJS("myObject.variantProperty === 'bar'"), sTrue);
m_myObject->setVariantProperty(42);
QCOMPARE(evalJS("myObject.variantProperty === 42"), sTrue);
- m_myObject->setVariantProperty(qVariantFromValue(QBrush()));
+ m_myObject->setVariantProperty(QVariant::fromValue(QBrush()));
//XFAIL
// QCOMPARE(evalJS("typeof myObject.variantProperty"), sVariant);
@@ -1240,7 +1240,7 @@ void tst_QWebFrame::callQtInvokable()
/* XFAIL - variant support
m_myObject->resetQtFunctionInvoked();
{
- m_myObject->setVariantProperty(qVariantFromValue(QBrush()));
+ m_myObject->setVariantProperty(QVariant::fromValue(QBrush()));
QVariant ret = evalJS("myObject.myInvokableWithVariantArg(myObject.variantProperty)");
QVERIFY(ret.isVariant());
QCOMPARE(m_myObject->qtFunctionInvoked(), 15);
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp
index 76927494b3..806e2b1b38 100644
--- a/src/activeqt/container/qaxbase.cpp
+++ b/src/activeqt/container/qaxbase.cpp
@@ -3540,7 +3540,7 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v)
proptype = 0;
} else if (t == QVariant::UserType) {
qvar = QVariant(qRegisterMetaType<void*>(prop.typeName()), (void**)v[0]);
-// qVariantSetValue(qvar, *(void**)v[0], prop.typeName());
+// qvar.setValue(*(void**)v[0], prop.typeName());
} else {
proptype = d->metaObject()->propertyType(propname);
qvar = QVariant(t, v[0]);
@@ -3628,9 +3628,9 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v)
if (!qvar.isValid()) {
if (type == "IDispatch*")
- qVariantSetValue(qvar, *(IDispatch**)v[p+1]);
+ qvar.setValue(*(IDispatch**)v[p+1]);
else if (type == "IUnknown*")
- qVariantSetValue(qvar, *(IUnknown**)v[p+1]);
+ qvar.setValue(*(IUnknown**)v[p+1]);
else if (type == "QVariant")
qvar = *(QVariant*)v[p + 1];
else if (mo->indexOfEnumerator(type) != -1)
@@ -4395,15 +4395,15 @@ QVariant QAxBase::asVariant() const
QByteArray cn(className());
if (cn == "QAxObject" || cn == "QAxWidget" || cn == "QAxBase") {
if (d->dispatch())
- qVariantSetValue(qvar, d->dispatch());
+ qvar.setValue(d->dispatch());
else if (d->ptr)
- qVariantSetValue(qvar, d->ptr);
+ qvar.setValue(d->ptr);
} else {
cn = cn.mid(cn.lastIndexOf(':') + 1);
QObject *object = qObject();
if (QMetaType::type(cn))
qvar = QVariant(qRegisterMetaType<QObject*>(cn + '*'), &object);
-// qVariantSetValue(qvar, qObject(), cn + '*');
+// qvar.setValue(qObject(), cn + '*');
}
return qvar;
diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp
index 7afce5bf2b..d3f736bdc5 100644
--- a/src/activeqt/container/qaxwidget.cpp
+++ b/src/activeqt/container/qaxwidget.cpp
@@ -1163,7 +1163,7 @@ HRESULT WINAPI QAxClientSite::InsertMenus(HMENU /*hmenuShared*/, LPOLEMENUGROUPW
AX_DEBUG(QAxClientSite::InsertMenus);
QMenuBar *mb = menuBar;
if (!mb)
- mb = qFindChild<QMenuBar*>(widget->window());
+ mb = widget->window()->findChild<QMenuBar*>();
if (!mb)
return E_NOTIMPL;
menuBar = mb;
@@ -1309,7 +1309,7 @@ HRESULT WINAPI QAxClientSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND
m_menuOwner = hwndActiveObject;
QMenuBar *mb = menuBar;
if (!mb)
- mb = qFindChild<QMenuBar*>(widget->window());
+ mb = widget->window()->findChild<QMenuBar*>();
if (!mb)
return E_NOTIMPL;
menuBar = mb;
diff --git a/src/activeqt/control/qaxserver.cpp b/src/activeqt/control/qaxserver.cpp
index 7728e50ed2..2512f0589d 100644
--- a/src/activeqt/control/qaxserver.cpp
+++ b/src/activeqt/control/qaxserver.cpp
@@ -285,7 +285,7 @@ HRESULT UpdateRegistry(BOOL bRegister)
|OLEMISC_RECOMPOSEONRESIZE;
if (!control)
olemisc |= OLEMISC_INVISIBLEATRUNTIME;
- else if (qFindChild<QMenuBar*>(object) && !qax_disable_inplaceframe)
+ else if (object->findChild<QMenuBar*>() && !qax_disable_inplaceframe)
olemisc |= OLEMISC_WANTSTOMENUMERGE;
settings.setValue(QLatin1Char('/') + module + QLatin1Char('.') + className + QLatin1Char('.') + classMajorVersion + QLatin1String("/."), className + QLatin1String(" Class"));
diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp
index d8e7ea3ff5..d8332286ff 100644
--- a/src/activeqt/control/qaxserverbase.cpp
+++ b/src/activeqt/control/qaxserverbase.cpp
@@ -1313,7 +1313,7 @@ bool QAxServerBase::internalCreate()
// install an event filter for stock events
if (isWidget) {
qt.object->installEventFilter(this);
- const QList<QWidget*> children = qFindChildren<QWidget*>(qt.object);
+ const QList<QWidget*> children = qt.object->findChildren<QWidget*>();
QList<QWidget*>::ConstIterator it = children.constBegin();
while (it != children.constEnd()) {
(*it)->installEventFilter(this);
@@ -2047,10 +2047,10 @@ int QAxServerBase::qt_metacall(QMetaObject::Call call, int index, void **argv)
if (vt == QVariant::UserType) {
if (ptype.endsWith('*')) {
variant = QVariant(QMetaType::type(ptype), (void**)argv[p+1]);
- // qVariantSetValue(variant, *(void**)(argv[p + 1]), ptype);
+ // variant.setValue(*(void**)(argv[p + 1]), ptype);
} else {
variant = QVariant(QMetaType::type(ptype), argv[p+1]);
- // qVariantSetValue(variant, argv[p + 1], ptype);
+ // variant.setValue(argv[p + 1], ptype);
}
} else {
variant = QVariant(vt, argv[p + 1]);
@@ -2537,7 +2537,7 @@ HRESULT WINAPI QAxServerBase::Invoke(DISPID dispidMember, REFIID riid,
if (!type.isEmpty() && pvarResult) {
if (!varp[0].isValid() && type != "QVariant")
varp[0] = QVariant(QMetaType::type(type), argv_pointer);
-// qVariantSetValue(varp[0], argv_pointer[0], type);
+// varp[0].setValue(argv_pointer[0], type);
ok = QVariantToVARIANT(varp[0], *pvarResult, type);
}
}
@@ -3325,7 +3325,7 @@ HRESULT WINAPI QAxServerBase::OnAmbientPropertyChange(DISPID dispID)
break;
{
QVariant qvar = VARIANTToQVariant(var, "QFont", QVariant::Font);
- QFont qfont = qVariantValue<QFont>(qvar);
+ QFont qfont = qvariant_cast<QFont>(qvar);
qt.widget->setFont(qfont);
}
break;
@@ -3818,7 +3818,7 @@ HRESULT QAxServerBase::internalActivate()
// Gone active by now, take care of UIACTIVATE
canTakeFocus = qt.widget->focusPolicy() != Qt::NoFocus && !inDesignMode;
if (!canTakeFocus && !inDesignMode) {
- QList<QWidget*> widgets = qFindChildren<QWidget*>(qt.widget);
+ QList<QWidget*> widgets = qt.widget->findChildren<QWidget*>();
for (int w = 0; w < widgets.count(); ++w) {
QWidget *widget = widgets[w];
canTakeFocus = widget->focusPolicy() != Qt::NoFocus;
@@ -3844,13 +3844,13 @@ HRESULT QAxServerBase::internalActivate()
if (m_spInPlaceFrame) {
hr = m_spInPlaceFrame->SetActiveObject(this, QStringToBSTR(class_name));
if (!FAILED(hr)) {
- menuBar = (qt.widget && !qax_disable_inplaceframe) ? qFindChild<QMenuBar*>(qt.widget) : 0;
+ menuBar = (qt.widget && !qax_disable_inplaceframe) ? qt.widget->findChild<QMenuBar*>() : 0;
if (menuBar && !menuBar->isVisible()) {
createMenu(menuBar);
menuBar->hide();
menuBar->installEventFilter(this);
}
- statusBar = qt.widget ? qFindChild<QStatusBar*>(qt.widget) : 0;
+ statusBar = qt.widget ? qt.widget->findChild<QStatusBar*>() : 0;
if (statusBar && !statusBar->isVisible()) {
const int index = statusBar->metaObject()->indexOfSignal("messageChanged(QString)");
QMetaObject::connect(statusBar, index, this, -1);
diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp
index 957733e534..6ed973823c 100644
--- a/src/activeqt/shared/qaxtypes.cpp
+++ b/src/activeqt/shared/qaxtypes.cpp
@@ -954,20 +954,20 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
break;
case VT_I4:
if (type == QVariant::Color || (!type && typeName == "QColor"))
- var = qVariantFromValue(OLEColorToQColor(arg.lVal));
+ var = QVariant::fromValue(OLEColorToQColor(arg.lVal));
#ifndef QT_NO_CURSOR
else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
- var = qVariantFromValue(QCursor(static_cast<Qt::CursorShape>(arg.lVal)));
+ var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(arg.lVal)));
#endif
else
var = (int)arg.lVal;
break;
case VT_I4|VT_BYREF:
if (type == QVariant::Color || (!type && typeName == "QColor"))
- var = qVariantFromValue(OLEColorToQColor((int)*arg.plVal));
+ var = QVariant::fromValue(OLEColorToQColor((int)*arg.plVal));
#ifndef QT_NO_CURSOR
else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
- var = qVariantFromValue(QCursor(static_cast<Qt::CursorShape>(*arg.plVal)));
+ var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(*arg.plVal)));
#endif
else
var = (int)*arg.plVal;
@@ -992,20 +992,20 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
break;
case VT_UI4:
if (type == QVariant::Color || (!type && typeName == "QColor"))
- var = qVariantFromValue(OLEColorToQColor(arg.ulVal));
+ var = QVariant::fromValue(OLEColorToQColor(arg.ulVal));
#ifndef QT_NO_CURSOR
else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
- var = qVariantFromValue(QCursor(static_cast<Qt::CursorShape>(arg.ulVal)));
+ var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(arg.ulVal)));
#endif
else
var = (int)arg.ulVal;
break;
case VT_UI4|VT_BYREF:
if (type == QVariant::Color || (!type && typeName == "QColor"))
- var = qVariantFromValue(OLEColorToQColor((uint)*arg.pulVal));
+ var = QVariant::fromValue(OLEColorToQColor((uint)*arg.pulVal));
#ifndef QT_NO_CURSOR
else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
- var = qVariantFromValue(QCursor(static_cast<Qt::CursorShape>(*arg.pulVal)));
+ var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(*arg.pulVal)));
#endif
else
var = (int)*arg.pulVal;
@@ -1084,20 +1084,20 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
if (disp)
disp->QueryInterface(IID_IFont, (void**)&ifont);
if (ifont) {
- var = qVariantFromValue(IFontToQFont(ifont));
+ var = QVariant::fromValue(IFontToQFont(ifont));
ifont->Release();
} else {
- var = qVariantFromValue(QFont());
+ var = QVariant::fromValue(QFont());
}
} else if (type == QVariant::Pixmap || (!type && (typeName == "QPixmap" || typeName == "QPixmap*"))) {
IPicture *ipic = 0;
if (disp)
disp->QueryInterface(IID_IPicture, (void**)&ipic);
if (ipic) {
- var = qVariantFromValue(IPictureToQPixmap(ipic));
+ var = QVariant::fromValue(IPictureToQPixmap(ipic));
ipic->Release();
} else {
- var = qVariantFromValue(QPixmap());
+ var = QVariant::fromValue(QPixmap());
}
} else {
#ifdef QAX_SERVER
@@ -1118,7 +1118,7 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
#ifndef QAX_SERVER
if (typeName == "QVariant") {
QAxObject *object = new QAxObject(disp);
- var = qVariantFromValue<QAxObject*>(object);
+ var = QVariant::fromValue<QAxObject*>(object);
} else if (typeName != "IDispatch*" && QMetaType::type(typeName)) {
QByteArray typeNameStr = QByteArray(typeName);
int pIndex = typeName.lastIndexOf('*');
@@ -1145,7 +1145,7 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
unkn = *arg.ppunkVal;
else
unkn = arg.punkVal;
- qVariantSetValue(var, unkn);
+ var.setValue(unkn);
}
break;
case VT_ARRAY|VT_VARIANT:
diff --git a/src/corelib/concurrent/qfuture.h b/src/corelib/concurrent/qfuture.h
index 02ae40a97c..2856f5e7ce 100644
--- a/src/corelib/concurrent/qfuture.h
+++ b/src/corelib/concurrent/qfuture.h
@@ -210,7 +210,7 @@ public:
bool operator==(const QFuture &other) const { return (d == other.d); }
bool operator!=(const QFuture &other) const { return (d != other.d); }
-#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(Q_CC_XLC)
+#if !defined(Q_CC_XLC)
template <typename T>
QFuture(const QFuture<T> &other)
: d(other.d)
diff --git a/src/corelib/concurrent/qfuturewatcher.cpp b/src/corelib/concurrent/qfuturewatcher.cpp
index d4573c6051..21b0789a8d 100644
--- a/src/corelib/concurrent/qfuturewatcher.cpp
+++ b/src/corelib/concurrent/qfuturewatcher.cpp
@@ -359,6 +359,15 @@ void QFutureWatcherBase::connectNotify(const char * signal)
Q_D(QFutureWatcherBase);
if (qstrcmp(signal, SIGNAL(resultReadyAt(int))) == 0)
d->resultAtConnected.ref();
+#ifndef QT_NO_DEBUG
+ if (qstrcmp(signal, SIGNAL(finished())) == 0) {
+ if (futureInterface().isRunning()) {
+ //connections should be established before calling stFuture to avoid race.
+ // (The future could finish before the connection is made.)
+ qWarning("QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race");
+ }
+ }
+#endif
}
void QFutureWatcherBase::disconnectNotify(const char * signal)
diff --git a/src/corelib/concurrent/qtconcurrentcompilertest.h b/src/corelib/concurrent/qtconcurrentcompilertest.h
index 982a50c274..4fbb3d76ee 100644
--- a/src/corelib/concurrent/qtconcurrentcompilertest.h
+++ b/src/corelib/concurrent/qtconcurrentcompilertest.h
@@ -51,12 +51,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Core)
-#ifdef Q_CC_MSVC
-# if _MSC_VER < 1300
-# define QT_CONURRENT_NONSTANDARD_COMPILER
-# endif
-#endif
-
#if defined (Q_CC_MSVC) && (_MSC_VER < 1300)
# define QT_TYPENAME
#else
diff --git a/src/corelib/concurrent/qtconcurrentiteratekernel.h b/src/corelib/concurrent/qtconcurrentiteratekernel.h
index 23aaae8a36..29d276be98 100644
--- a/src/corelib/concurrent/qtconcurrentiteratekernel.h
+++ b/src/corelib/concurrent/qtconcurrentiteratekernel.h
@@ -184,12 +184,9 @@ public:
#if defined (QT_NO_STL)
: begin(_begin), end(_end), current(_begin), currentIndex(0),
forIteration(false), progressReportingEnabled(true)
-#elif !defined(QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION)
+#else
: begin(_begin), end(_end), current(_begin), currentIndex(0),
forIteration(selectIteration(typename std::iterator_traits<Iterator>::iterator_category())), progressReportingEnabled(true)
-#else
- : begin(_begin), end(_end), currentIndex(0),
- forIteration(selectIteration(std::iterator_category(_begin))), progressReportingEnabled(true)
#endif
{
#if defined (QT_NO_STL)
diff --git a/src/corelib/concurrent/qthreadpool.cpp b/src/corelib/concurrent/qthreadpool.cpp
index 9e4189edec..f25a4944ae 100644
--- a/src/corelib/concurrent/qthreadpool.cpp
+++ b/src/corelib/concurrent/qthreadpool.cpp
@@ -41,6 +41,7 @@
#include "qthreadpool.h"
#include "qthreadpool_p.h"
+#include "qelapsedtimer.h"
#ifndef QT_NO_THREAD
@@ -288,11 +289,21 @@ void QThreadPoolPrivate::reset()
isExiting = false;
}
-void QThreadPoolPrivate::waitForDone()
+bool QThreadPoolPrivate::waitForDone(int msecs)
{
QMutexLocker locker(&mutex);
- while (!(queue.isEmpty() && activeThreads == 0))
- noActiveThreads.wait(locker.mutex());
+ if (msecs < 0) {
+ while (!(queue.isEmpty() && activeThreads == 0))
+ noActiveThreads.wait(locker.mutex());
+ } else {
+ QElapsedTimer timer;
+ timer.start();
+ int t;
+ while (!(queue.isEmpty() && activeThreads == 0) &&
+ ((t = msecs - timer.elapsed()) > 0))
+ noActiveThreads.wait(locker.mutex(), t);
+ }
+ return queue.isEmpty() && activeThreads == 0;
}
/*! \internal
@@ -617,6 +628,23 @@ void QThreadPool::waitForDone()
d->reset();
}
+/*!
+ \overload waitForDone()
+ \since 4.8
+
+ Waits up to \a msecs milliseconds for all threads to exit and removes all
+ threads from the thread pool. Returns true if all threads were removed;
+ otherwise it returns false.
+*/
+bool QThreadPool::waitForDone(int msecs)
+{
+ Q_D(QThreadPool);
+ bool rc = d->waitForDone(msecs);
+ if (rc)
+ d->reset();
+ return rc;
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/concurrent/qthreadpool.h b/src/corelib/concurrent/qthreadpool.h
index cc1e05986b..0bd18843c1 100644
--- a/src/corelib/concurrent/qthreadpool.h
+++ b/src/corelib/concurrent/qthreadpool.h
@@ -85,6 +85,7 @@ public:
void releaseThread();
void waitForDone();
+ bool waitForDone(int msecs);
};
QT_END_NAMESPACE
diff --git a/src/corelib/concurrent/qthreadpool_p.h b/src/corelib/concurrent/qthreadpool_p.h
index 8a2cf98517..3d2d6be661 100644
--- a/src/corelib/concurrent/qthreadpool_p.h
+++ b/src/corelib/concurrent/qthreadpool_p.h
@@ -82,7 +82,7 @@ public:
void startThread(QRunnable *runnable = 0);
void reset();
- void waitForDone();
+ bool waitForDone(int msecs = -1);
bool startFrontRunnable();
void stealRunnable(QRunnable *);
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index d53504abe4..e0e946bb4b 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -89,7 +89,7 @@ template <typename T> inline void qToUnaligned(const T src, uchar *dest)
* and return the value in host-endian encoding.
* There is no requirement that \a src must be aligned.
*/
-#if defined Q_CC_MSVC && _MSC_VER < 1300 || defined Q_CC_SUN
+#if defined Q_CC_SUN
inline quint64 qFromLittleEndian_helper(const uchar *src, quint64 *dest)
{
return 0
@@ -177,7 +177,7 @@ template <> inline qint16 qFromLittleEndian<qint16>(const uchar *src)
* and return the value in host-endian encoding.
* There is no requirement that \a src must be aligned.
*/
-#if defined Q_CC_MSVC && _MSC_VER < 1300 || defined Q_CC_SUN
+#if defined Q_CC_SUN
inline quint64 qFromBigEndian_helper(const uchar *src, quint64 *dest)
{
return 0
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 401af8574a..c992735870 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1984,7 +1984,7 @@ QSysInfo::SymbianVersion QSysInfo::symbianVersion()
*/
void qt_check_pointer(const char *n, int l)
{
- qWarning("In file %s, line %d: Out of memory", n, l);
+ qFatal("In file %s, line %d: Out of memory", n, l);
}
/* \internal
@@ -2215,7 +2215,8 @@ void qt_message_output(QtMsgType msgType, const char *buf)
_LIT(format, "[Qt Message] %S");
const int maxBlockSize = 256 - ((const TDesC &)format).Length();
const TPtrC8 ptr(reinterpret_cast<const TUint8*>(buf));
- HBufC* hbuffer = q_check_ptr(HBufC::New(qMin(maxBlockSize, ptr.Length())));
+ HBufC* hbuffer = HBufC::New(qMin(maxBlockSize, ptr.Length()));
+ Q_CHECK_PTR(hbuffer);
for (int i = 0; i < ptr.Length(); i += hbuffer->Length()) {
hbuffer->Des().Copy(ptr.Mid(i, qMin(maxBlockSize, ptr.Length()-i)));
RDebug::Print(format, hbuffer);
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 8f27b03497..02196e4af9 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -44,11 +44,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "4.7.0"
+#define QT_VERSION_STR "4.8.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x040700
+#define QT_VERSION 0x040800
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -383,31 +383,12 @@ namespace QT_NAMESPACE {}
#elif defined(_MSC_VER)
# define Q_CC_MSVC
-/* proper support of bool for _MSC_VER >= 1100 */
+# define Q_CC_MSVC_NET
# define Q_CANNOT_DELETE_CONSTANT
# define Q_OUTOFLINE_TEMPLATE inline
# define Q_NO_TEMPLATE_FRIENDS
-# define QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
-# define Q_ALIGNOF(type) __alignof(type)
-# define Q_DECL_ALIGN(n) __declspec(align(n))
-
-/* Visual C++.Net issues for _MSC_VER >= 1300 */
-# if _MSC_VER >= 1300
-# define Q_CC_MSVC_NET
-# if _MSC_VER < 1310 || (defined(Q_OS_WIN64) && defined(_M_IA64))
-# define Q_TYPENAME
-# else
-# undef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
-# endif
-# else
-# define Q_NO_USING_KEYWORD
-# define QT_NO_MEMBER_TEMPLATES
-# endif
-# if _MSC_VER < 1310
-# define QT_NO_QOBJECT_CHECK
-# define Q_TYPENAME
-# define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
-# endif
+# define Q_ALIGNOF(type) __alignof(type)
+# define Q_DECL_ALIGN(n) __declspec(align(n))
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
# if defined(__INTEL_COMPILER)
# define Q_CC_INTEL
@@ -493,6 +474,26 @@ namespace QT_NAMESPACE {}
# define QT_NO_ARM_EABI
# endif
# endif
+# if defined(__GXX_EXPERIMENTAL_CXX0X__)
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+ /* C++0x features supported in GCC 4.3: */
+# define Q_COMPILER_RVALUE_REFS
+# endif
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404
+ /* C++0x features supported in GCC 4.4: */
+# define Q_COMPILER_VARIADIC_TEMPLATES
+# define Q_COMPILER_AUTO_TYPE
+# define Q_COMPILER_EXTERN_TEMPLATES
+# define Q_COMPILER_DEFAULT_DELETE_MEMBERS
+# define Q_COMPILER_CLASS_ENUM
+# define Q_COMPILER_INITIALIZER_LISTS
+# endif
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
+ /* C++0x features supported in GCC 4.5: */
+# define Q_COMPILER_LAMBDA
+# define Q_COMPILER_UNICODE_STRINGS
+# endif
+# endif
/* IBM compiler versions are a bit messy. There are actually two products:
the C product, and the C++ product. The C++ compiler is always packaged
@@ -924,10 +925,10 @@ redefine to built-in booleans to make autotests work properly */
#endif
/*
- Proper for-scoping in VC++6 and MIPSpro CC
+ Proper for-scoping in MIPSpro CC
*/
#ifndef QT_NO_KEYWORDS
-# if (defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) && !defined(Q_CC_INTEL)) || defined(Q_CC_MIPS) || (defined(Q_CC_HPACC) && defined(__ia64))
+# if defined(Q_CC_MIPS) || (defined(Q_CC_HPACC) && defined(__ia64))
# define for if(0){}else for
# endif
#endif
@@ -951,7 +952,7 @@ redefine to built-in booleans to make autotests work properly */
# define Q_DECL_DEPRECATED Q_DECL_DEPRECATED
#elif (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && (__GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2))) || defined(Q_CC_RVCT)
# define Q_DECL_DEPRECATED __attribute__ ((__deprecated__))
-#elif defined(Q_CC_MSVC) && (_MSC_VER >= 1300)
+#elif defined(Q_CC_MSVC)
# define Q_DECL_DEPRECATED __declspec(deprecated)
# if defined (Q_CC_INTEL)
# define Q_DECL_VARIABLE_DEPRECATED
@@ -1055,7 +1056,7 @@ redefine to built-in booleans to make autotests work properly */
#else
# define QT_FASTCALL
#endif
-# elif defined(Q_CC_MSVC) && (_MSC_VER > 1300 || defined(Q_CC_INTEL))
+# elif defined(Q_CC_MSVC)
# define QT_FASTCALL __fastcall
# else
# define QT_FASTCALL
@@ -1362,15 +1363,22 @@ class QDataStream;
# else
# define Q_GUI_EXPORT_INLINE inline
# endif
+# if defined(QT_BUILD_COMPAT_LIB)
+# define Q_COMPAT_EXPORT_INLINE Q_COMPAT_EXPORT inline
+# else
+# define Q_COMPAT_EXPORT_INLINE inline
+# endif
#elif defined(Q_CC_RVCT)
// we force RVCT not to export inlines by passing --visibility_inlines_hidden
// so we need to just inline it, rather than exporting and inlining
// note: this affects the contents of the DEF files (ie. these functions do not appear)
# define Q_CORE_EXPORT_INLINE inline
# define Q_GUI_EXPORT_INLINE inline
+# define Q_COMPAT_EXPORT_INLINE inline
#else
# define Q_CORE_EXPORT_INLINE Q_CORE_EXPORT inline
# define Q_GUI_EXPORT_INLINE Q_GUI_EXPORT inline
+# define Q_COMPAT_EXPORT_INLINE Q_COMPAT_EXPORT inline
#endif
/*
@@ -1702,7 +1710,7 @@ Q_CORE_EXPORT void qBadAlloc();
#ifdef QT_NO_EXCEPTIONS
# if defined(QT_NO_DEBUG)
-# define Q_CHECK_PTR(p) qt_noop();
+# define Q_CHECK_PTR(p) qt_noop()
# else
# define Q_CHECK_PTR(p) do {if(!(p))qt_check_pointer(__FILE__,__LINE__);} while (0)
# endif
@@ -1716,12 +1724,7 @@ inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; }
#if (defined(Q_CC_GNU) && !defined(Q_OS_SOLARIS)) || defined(Q_CC_HPACC) || defined(Q_CC_DIAB)
# define Q_FUNC_INFO __PRETTY_FUNCTION__
#elif defined(_MSC_VER)
- /* MSVC 2002 doesn't have __FUNCSIG__ nor can it handle QT_STRINGIFY. */
-# if _MSC_VER <= 1300
-# define Q_FUNC_INFO __FILE__ "(line number unavailable)"
-# else
-# define Q_FUNC_INFO __FUNCSIG__
-# endif
+# define Q_FUNC_INFO __FUNCSIG__
#else
# if defined(Q_OS_SOLARIS) || defined(Q_CC_XLC) || defined(Q_OS_SYMBIAN)
# define Q_FUNC_INFO __FILE__ "(line number unavailable)"
@@ -1971,8 +1974,6 @@ static inline bool qIsNull(float f)
qIsDetached - data sharing functionality
*/
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
-
/*
The catch-all template.
*/
@@ -2005,28 +2006,6 @@ public:
};
};
-#else
-
-template <typename T> char QTypeInfoHelper(T*(*)());
-void* QTypeInfoHelper(...);
-
-template <typename T> inline bool qIsDetached(T &) { return true; }
-
-template <typename T>
-class QTypeInfo
-{
-public:
- enum {
- isPointer = (1 == sizeof(QTypeInfoHelper((T(*)())0))),
- isComplex = !isPointer,
- isStatic = !isPointer,
- isLarge = (sizeof(T)>sizeof(void*)),
- isDummy = false
- };
-};
-
-#endif /* QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION */
-
/*
Specialize a specific type with:
@@ -2043,8 +2022,7 @@ enum { /* TYPEINFO flags */
Q_DUMMY_TYPE = 0x4
};
-#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
-template <> \
+#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
class QTypeInfo<TYPE > \
{ \
public: \
@@ -2058,6 +2036,11 @@ public: \
static inline const char *name() { return #TYPE; } \
}
+#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
+template<> \
+Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
+
+
template <typename T>
inline void qSwap(T &value1, T &value2)
{
@@ -2140,10 +2123,6 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
# pragma warning(disable: 4231) /* nonstandard extension used : 'extern' before template explicit instantiation */
# pragma warning(disable: 4710) /* function not inlined */
# pragma warning(disable: 4530) /* C++ exception handler used, but unwind semantics are not enabled. Specify -GX */
-# if _MSC_VER < 1300
-# pragma warning(disable: 4284) /* return type for 'type1::operator ->' is 'type2 *' */
- /* (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation) */
-# endif
# elif defined(Q_CC_BOR)
# pragma option -w-inl
# pragma option -w-aus
@@ -2217,13 +2196,9 @@ public:
#define Q_DECLARE_FLAGS(Flags, Enum)\
typedef QFlags<Enum> Flags;
-#if defined Q_CC_MSVC && _MSC_VER < 1300
-# define Q_DECLARE_INCOMPATIBLE_FLAGS(Flags)
-#else
-# define Q_DECLARE_INCOMPATIBLE_FLAGS(Flags) \
+#define Q_DECLARE_INCOMPATIBLE_FLAGS(Flags) \
inline QIncompatibleFlag operator|(Flags::enum_type f1, int f2) \
{ return QIncompatibleFlag(int(f1) | f2); }
-#endif
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) \
@@ -2280,9 +2255,9 @@ template <typename T>
inline const QForeachContainer<T> *qForeachContainer(const QForeachContainerBase *base, const T *)
{ return static_cast<const QForeachContainer<T> *>(base); }
-#if (defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) && !defined(Q_CC_INTEL)) || defined(Q_CC_MIPS)
+#if defined(Q_CC_MIPS)
/*
- Proper for-scoping in VC++6 and MIPSpro CC
+ Proper for-scoping in MIPSpro CC
*/
# define Q_FOREACH(variable,container) \
if(0){}else \
@@ -2639,12 +2614,6 @@ QT_LICENSED_MODULE(DBus)
# define QT_NO_QFUTURE
#endif
-// MSVC 6.0 and MSVC .NET 2002, can`t handle the map(), etc templates,
-// but the QFuture class compiles.
-#if (defined(Q_CC_MSVC) && _MSC_VER <= 1300)
-# define QT_NO_CONCURRENT
-#endif
-
// gcc 3 version has problems with some of the
// map/filter overloads.
#if defined(Q_CC_GNU) && (__GNUC__ < 4)
@@ -2663,6 +2632,12 @@ QT_LICENSED_MODULE(DBus)
# define QT_NO_PROCESS
#endif
+#if defined (__ELF__)
+# if defined (Q_OS_LINUX) || defined (Q_OS_SOLARIS) || defined (Q_OS_FREEBSD) || defined (Q_OS_OPENBSD) || defined (Q_OS_IRIX)
+# define Q_OF_ELF
+# endif
+#endif
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 395283666c..a531009c39 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -534,6 +534,7 @@ public:
AA_DontUseNativeMenuBar = 6,
AA_MacDontSwapCtrlAndMeta = 7,
AA_S60DontConstructApplicationPanes = 8,
+ AA_X11InitThreads = 9,
// Add new attributes before this line
AA_AttributeCount
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 5cd7f0e35d..137da0ee45 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -156,6 +156,11 @@
whole lifetime. This attribute must be set before QApplication is
constructed.
+ \value AA_X11InitThreads Calls XInitThreads() as part of the QApplication
+ construction in order to make Xlib calls thread-safe. This
+ attribute must be set before QApplication is constructed.
+
+
\omitvalue AA_AttributeCount
*/
diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp
index d6b6f1136b..37a093c513 100644
--- a/src/corelib/io/qabstractfileengine.cpp
+++ b/src/corelib/io/qabstractfileengine.cpp
@@ -41,12 +41,16 @@
#include "qabstractfileengine.h"
#include "private/qabstractfileengine_p.h"
+#ifdef QT_BUILD_CORE_LIB
+#include "private/qresource_p.h"
+#endif
#include "qdatetime.h"
#include "qreadwritelock.h"
#include "qvariant.h"
// built-in handlers
#include "qfsfileengine.h"
#include "qdiriterator.h"
+#include "qstringbuilder.h"
QT_BEGIN_NAMESPACE
@@ -94,6 +98,8 @@ QT_BEGIN_NAMESPACE
\sa QAbstractFileEngine, QAbstractFileEngine::create()
*/
+static bool qt_file_engine_handlers_in_use = false;
+
/*
All application-wide handlers are stored in this list. The mutex must be
acquired to ensure thread safety.
@@ -123,6 +129,7 @@ Q_GLOBAL_STATIC(QAbstractFileEngineHandlerList, fileEngineHandlers)
QAbstractFileEngineHandler::QAbstractFileEngineHandler()
{
QWriteLocker locker(fileEngineHandlerMutex());
+ qt_file_engine_handlers_in_use = true;
fileEngineHandlers()->prepend(this);
}
@@ -134,8 +141,12 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler()
{
QWriteLocker locker(fileEngineHandlerMutex());
// Remove this handler from the handler list only if the list is valid.
- if (!qt_abstractfileenginehandlerlist_shutDown)
- fileEngineHandlers()->removeAll(this);
+ if (!qt_abstractfileenginehandlerlist_shutDown) {
+ QAbstractFileEngineHandlerList *handlers = fileEngineHandlers();
+ handlers->removeOne(this);
+ if (handlers->isEmpty())
+ qt_file_engine_handlers_in_use = false;
+ }
}
/*!
@@ -166,33 +177,48 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler()
*/
QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName)
{
- {
+ if (qt_file_engine_handlers_in_use) {
QReadLocker locker(fileEngineHandlerMutex());
// check for registered handlers that can load the file
- for (int i = 0; i < fileEngineHandlers()->size(); i++) {
- if (QAbstractFileEngine *ret = fileEngineHandlers()->at(i)->create(fileName))
+ QAbstractFileEngineHandlerList *handlers = fileEngineHandlers();
+ for (int i = 0; i < handlers->size(); i++) {
+ if (QAbstractFileEngine *ret = handlers->at(i)->create(fileName))
return ret;
}
}
#ifdef QT_BUILD_CORE_LIB
- if (!fileName.startsWith(QLatin1Char('/'))) {
- int prefixSeparator = fileName.indexOf(QLatin1Char(':'));
- if (prefixSeparator > 1) {
- QString prefix = fileName.left(prefixSeparator);
- QString fileNameWithoutPrefix = fileName.mid(prefixSeparator + 1).prepend(QLatin1Char('/'));
- const QStringList &paths = QDir::searchPaths(prefix);
+ for (int prefixSeparator = 0; prefixSeparator < fileName.size(); ++prefixSeparator) {
+ QChar const ch = fileName[prefixSeparator];
+ if (ch == QLatin1Char('/'))
+ break;
+
+ if (ch == QLatin1Char(':')) {
+ if (prefixSeparator == 0)
+ return new QResourceFileEngine(fileName);
+
+ if (prefixSeparator == 1)
+ break;
+
+ const QStringList &paths = QDir::searchPaths(fileName.left(prefixSeparator));
for (int i = 0; i < paths.count(); i++) {
- QString path = paths.at(i);
- path.append(fileNameWithoutPrefix);
- QAbstractFileEngine *engine = create(path);
+ QAbstractFileEngine *engine = create(paths.at(i) % QLatin1Char('/') % fileName.mid(prefixSeparator + 1));
if (engine && (engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag)) {
return engine;
}
delete engine;
}
+
+ break;
}
+
+ // There's no need to fully validate the prefix here. Consulting the
+ // unicode tables could be expensive and validation is already
+ // performed in QDir::setSearchPaths.
+ //
+ // if (!ch.isLetterOrNumber())
+ // break;
}
#endif
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 222ba8f5e4..774c4bc2d3 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -85,10 +85,11 @@ public:
Qt_4_4 = 10,
Qt_4_5 = 11,
Qt_4_6 = 12,
- Qt_4_7 = Qt_4_6
-#if QT_VERSION >= 0x040800
-#error Add the datastream version for this Qt version
+ Qt_4_7 = Qt_4_6,
Qt_4_8 = Qt_4_7
+#if QT_VERSION >= 0x040900
+#error Add the datastream version for this Qt version
+ Qt_4_9 = Qt_4_8
#endif
};
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 093312f412..a9d5ad4ab2 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -137,10 +137,8 @@ public:
inline QNoDebug &nospace() { return *this; }
inline QNoDebug &maybeSpace() { return *this; }
-#ifndef QT_NO_MEMBER_TEMPLATES
template<typename T>
inline QNoDebug &operator<<(const T &) { return *this; }
-#endif
};
Q_CORE_EXPORT_INLINE QDebug qCritical() { return QDebug(QtCriticalMsg); }
@@ -285,11 +283,6 @@ Q_CORE_EXPORT_INLINE QDebug qDebug() { return QDebug(QtDebugMsg); }
inline QNoDebug qDebug() { return QNoDebug(); }
#define qDebug QT_NO_QDEBUG_MACRO
-#ifdef QT_NO_MEMBER_TEMPLATES
-template<typename T>
-inline QNoDebug operator<<(QNoDebug debug, const T &) { return debug; }
-#endif
-
#endif
#if !defined(QT_NO_WARNING_OUTPUT)
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index efcc8f9540..426f61ee89 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -778,6 +778,7 @@ QString QDir::relativeFilePath(const QString &fileName) const
return result;
}
+#ifndef QT_NO_DEPRECATED
/*!
\obsolete
@@ -787,6 +788,7 @@ QString QDir::convertSeparators(const QString &pathName)
{
return toNativeSeparators(pathName);
}
+#endif
/*!
\since 4.2
@@ -1854,7 +1856,8 @@ QString QDir::homePath()
/*!
Returns the absolute path of the system's temporary directory.
- On Unix/Linux systems this is usually \c{/tmp}; on Windows this is
+ On Unix/Linux systems this is the path in the \c TMPDIR environment
+ variable or \c{/tmp} if \c TMPDIR is not defined. On Windows this is
usually the path in the \c TEMP or \c TMP environment
variable. Whether a directory separator is added to the end or
not, depends on the operating system.
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index 7e5fbac420..9eab24fa63 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -128,6 +128,10 @@ public:
QDir &operator=(const QDir &);
QDir &operator=(const QString &path);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QDir &operator=(QDir &&other)
+ { qSwap(d_ptr, other.d_ptr); return *this; }
+#endif
void setPath(const QString &path);
QString path() const;
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index f0128b1c56..aec75436ad 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -67,6 +67,10 @@ public:
~QFileInfo();
QFileInfo &operator=(const QFileInfo &fileinfo);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QFileInfo&operator=(QFileInfo &&other)
+ { qSwap(d_ptr, other.d_ptr); return *this; }
+#endif
bool operator==(const QFileInfo &fileinfo); // 5.0 - remove me
bool operator==(const QFileInfo &fileinfo) const;
inline bool operator!=(const QFileInfo &fileinfo) { return !(operator==(fileinfo)); } // 5.0 - remove me
diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp
index 249ce0f70d..71df3c237c 100644
--- a/src/corelib/io/qfilesystemwatcher_win.cpp
+++ b/src/corelib/io/qfilesystemwatcher_win.cpp
@@ -86,7 +86,8 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
while (it.hasNext()) {
QString path = it.next();
QString normalPath = path;
- if ((normalPath.endsWith(QLatin1Char('/')) || normalPath.endsWith(QLatin1Char('\\')))
+ if ((normalPath.endsWith(QLatin1Char('/')) && !normalPath.endsWith(QLatin1String(":/")))
+ || (normalPath.endsWith(QLatin1Char('\\')) && !normalPath.endsWith(QLatin1String(":\\")))
#ifdef Q_OS_WINCE
&& normalPath.size() > 1)
#else
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index a1ffb8119e..511a1a6634 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -189,9 +189,15 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path)
known.insert(path);
do {
#ifdef Q_OS_WIN
- // UNC, skip past the first two elements
- if (separatorPos == 0 && tmpPath.startsWith(QLatin1String("//")))
- separatorPos = tmpPath.indexOf(slash, 2);
+ if (separatorPos == 0) {
+ if (tmpPath.size() >= 2 && tmpPath.at(0) == slash && tmpPath.at(1) == slash) {
+ // UNC, skip past the first two elements
+ separatorPos = tmpPath.indexOf(slash, 2);
+ } else if (tmpPath.size() >= 3 && tmpPath.at(1) == QLatin1Char(':') && tmpPath.at(2) == slash) {
+ // volume root, skip since it can not be a symlink
+ separatorPos = 2;
+ }
+ }
if (separatorPos != -1)
#endif
separatorPos = tmpPath.indexOf(slash, separatorPos + 1);
@@ -208,6 +214,8 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path)
fi.setFile(prefix);
if (fi.isSymLink()) {
QString target = fi.symLinkTarget();
+ if(QFileInfo(target).isRelative())
+ target = fi.absolutePath() + slash + target;
if (separatorPos != -1) {
if (fi.isDir() && !target.endsWith(slash))
target.append(slash);
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index d83f7eec45..774932a28b 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -880,6 +880,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.'))
# if !defined(QWS) && defined(Q_OS_MAC)
|| _q_isMacHidden(d->filePath)
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ || d->st.st_flags & UF_HIDDEN
+# endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
# endif
) {
ret |= HiddenFlag;
@@ -1089,7 +1092,8 @@ QString QFSFileEngine::fileName(FileName file) const
int size = PATH_CHUNK_SIZE;
while (1) {
- s = q_check_ptr((char *) ::realloc(s, size));
+ s = (char *) ::realloc(s, size);
+ Q_CHECK_PTR(s);
len = ::readlink(d->nativeFilePath.constData(), s, size);
if (len < 0) {
::free(s);
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index d5c53bb950..c27a424bca 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -155,6 +155,8 @@ static TRUSTEE_W worldTrusteeW;
typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD);
static PtrGetUserProfileDirectoryW ptrGetUserProfileDirectoryW = 0;
+typedef BOOL (WINAPI *PtrGetVolumePathNamesForVolumeNameW)(LPCWSTR,LPWSTR,DWORD,PDWORD);
+static PtrGetVolumePathNamesForVolumeNameW ptrGetVolumePathNamesForVolumeNameW = 0;
QT_END_INCLUDE_NAMESPACE
@@ -213,6 +215,9 @@ void QFSFileEnginePrivate::resolveLibs()
HINSTANCE userenvHnd = QSystemLibrary::load(L"userenv");
if (userenvHnd)
ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW");
+ HINSTANCE kernel32 = LoadLibrary(L"kernel32");
+ if(kernel32)
+ ptrGetVolumePathNamesForVolumeNameW = (PtrGetVolumePathNamesForVolumeNameW)GetProcAddress(kernel32, "GetVolumePathNamesForVolumeNameW");
#endif
}
}
@@ -1286,7 +1291,12 @@ static QString readSymLink(const QString &link)
REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)qMalloc(bufsize);
DWORD retsize = 0;
if (::DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, 0, 0, rdb, bufsize, &retsize, 0)) {
- if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
+ if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
+ int length = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
+ int offset = rdb->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t);
+ const wchar_t* PathBuffer = &rdb->MountPointReparseBuffer.PathBuffer[offset];
+ result = QString::fromWCharArray(PathBuffer, length);
+ } else if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
int length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
int offset = rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t);
const wchar_t* PathBuffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[offset];
@@ -1298,6 +1308,20 @@ static QString readSymLink(const QString &link)
}
qFree(rdb);
CloseHandle(handle);
+
+#if !defined(QT_NO_LIBRARY)
+ QFSFileEnginePrivate::resolveLibs();
+ if (ptrGetVolumePathNamesForVolumeNameW) {
+ QRegExp matchVolName(QLatin1String("^Volume\\{([a-z]|[0-9]|-)+\\}\\\\"), Qt::CaseInsensitive);
+ if(matchVolName.indexIn(result) == 0) {
+ DWORD len;
+ wchar_t buffer[MAX_PATH];
+ QString volumeName = result.mid(0, matchVolName.matchedLength()).prepend(QLatin1String("\\\\?\\"));
+ if(ptrGetVolumePathNamesForVolumeNameW((wchar_t*)volumeName.utf16(), buffer, MAX_PATH, &len) != 0)
+ result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer));
+ }
+ }
+#endif
}
#else
Q_UNUSED(link);
@@ -1549,7 +1573,7 @@ bool QFSFileEnginePrivate::isSymlink() const
if (hFind != INVALID_HANDLE_VALUE) {
::FindClose(hFind);
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
- && findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
+ && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) {
is_link = true;
}
}
@@ -1649,10 +1673,12 @@ QString QFSFileEngine::fileName(FileName file) const
if (!isRelativePath()) {
#if !defined(Q_OS_WINCE)
- if ((d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':')
- && d->filePath.at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt
- d->filePath.startsWith(QLatin1Char('/')) // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt
- ) {
+ if (d->filePath.startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt
+ d->filePath.size() == 2 || // It's a drive letter that needs to get a working dir appended
+ (d->filePath.size() > 2 && d->filePath.at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt
+ d->filePath.contains(QLatin1String("/../")) || d->filePath.contains(QLatin1String("/./")) ||
+ d->filePath.endsWith(QLatin1String("/..")) || d->filePath.endsWith(QLatin1String("/.")))
+ {
ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->filePath));
} else {
ret = d->filePath;
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 26e587ded2..8544fbaf94 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -1633,6 +1633,12 @@ QString QIODevice::errorString() const
This function is called by QIODevice. Reimplement this function
when creating a subclass of QIODevice.
+ When reimplementing this function it is important that this function
+ reads all the required data before returning. This is required in order
+ for QDataStream to be able to operate on the class. QDataStream assumes
+ all the requested information was read and therefore does not retry reading
+ if there was a problem.
+
\sa read() readLine() writeData()
*/
@@ -1645,6 +1651,12 @@ QString QIODevice::errorString() const
This function is called by QIODevice. Reimplement this function
when creating a subclass of QIODevice.
+ When reimplementing this function it is important that this function
+ writes all the data available before returning. This is required in order
+ for QDataStream to be able to operate on the class. QDataStream assumes
+ all the information was written and therefore does not retry writing if
+ there was a problem.
+
\sa read() write()
*/
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index ce9c57ecea..929885c390 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1185,21 +1185,6 @@ QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot)
return false;
}
-//file type handler
-class QResourceFileEngineHandler : public QAbstractFileEngineHandler
-{
-public:
- QResourceFileEngineHandler() { }
- ~QResourceFileEngineHandler() { }
- QAbstractFileEngine *create(const QString &path) const;
-};
-QAbstractFileEngine *QResourceFileEngineHandler::create(const QString &path) const
-{
- if (path.size() > 0 && path.startsWith(QLatin1Char(':')))
- return new QResourceFileEngine(path);
- return 0;
-}
-
//resource engine
class QResourceFileEnginePrivate : public QAbstractFileEnginePrivate
{
@@ -1506,12 +1491,6 @@ bool QResourceFileEnginePrivate::unmap(uchar *ptr)
return true;
}
-//Initialization and cleanup
-Q_GLOBAL_STATIC(QResourceFileEngineHandler, resource_file_handler)
-
-static int qt_force_resource_init() { resource_file_handler(); return 1; }
-Q_CORE_EXPORT void qInitResourceIO() { resource_file_handler(); }
-static int qt_forced_resource_init = qt_force_resource_init();
-Q_CONSTRUCTOR_FUNCTION(qt_force_resource_init)
+Q_CORE_EXPORT void qInitResourceIO() { } // ### Qt 5: remove
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index edd6d2b701..f25c272e6e 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -252,9 +252,7 @@ bool QConfFile::isWritable() const
} else {
// Create the directories to the file.
QDir dir(fileInfo.absolutePath());
- if (dir.exists() && dir.isReadable()) {
- return true;
- } else {
+ if (!dir.exists()) {
if (!dir.mkpath(dir.absolutePath()))
return false;
}
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index d1fab2d84d..b122cd26fc 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -966,14 +966,14 @@ static void QT_FASTCALL _fragment(const char **ptr, QUrlParseData *parseData)
}
struct NameprepCaseFoldingEntry {
- int uc;
+ uint uc;
ushort mapping[4];
};
-inline bool operator<(int one, const NameprepCaseFoldingEntry &other)
+inline bool operator<(uint one, const NameprepCaseFoldingEntry &other)
{ return one < other.uc; }
-inline bool operator<(const NameprepCaseFoldingEntry &one, int other)
+inline bool operator<(const NameprepCaseFoldingEntry &one, uint other)
{ return one.uc < other; }
static const NameprepCaseFoldingEntry NameprepCaseFolding[] = {
@@ -1862,45 +1862,44 @@ static const NameprepCaseFoldingEntry NameprepCaseFolding[] = {
{ 0xFF38, { 0xFF58, 0x0000, 0x0000, 0x0000 } },
{ 0xFF39, { 0xFF59, 0x0000, 0x0000, 0x0000 } },
{ 0xFF3A, { 0xFF5A, 0x0000, 0x0000, 0x0000 } },
- // #####
-/* { 0x10400, { 0x10428, 0x0000, 0x0000, 0x0000 } },
- { 0x10401, { 0x10429, 0x0000, 0x0000, 0x0000 } },
- { 0x10402, { 0x1042A, 0x0000, 0x0000, 0x0000 } },
- { 0x10403, { 0x1042B, 0x0000, 0x0000, 0x0000 } },
- { 0x10404, { 0x1042C, 0x0000, 0x0000, 0x0000 } },
- { 0x10405, { 0x1042D, 0x0000, 0x0000, 0x0000 } },
- { 0x10406, { 0x1042E, 0x0000, 0x0000, 0x0000 } },
- { 0x10407, { 0x1042F, 0x0000, 0x0000, 0x0000 } },
- { 0x10408, { 0x10430, 0x0000, 0x0000, 0x0000 } },
- { 0x10409, { 0x10431, 0x0000, 0x0000, 0x0000 } },
- { 0x1040A, { 0x10432, 0x0000, 0x0000, 0x0000 } },
- { 0x1040B, { 0x10433, 0x0000, 0x0000, 0x0000 } },
- { 0x1040C, { 0x10434, 0x0000, 0x0000, 0x0000 } },
- { 0x1040D, { 0x10435, 0x0000, 0x0000, 0x0000 } },
- { 0x1040E, { 0x10436, 0x0000, 0x0000, 0x0000 } },
- { 0x1040F, { 0x10437, 0x0000, 0x0000, 0x0000 } },
- { 0x10410, { 0x10438, 0x0000, 0x0000, 0x0000 } },
- { 0x10411, { 0x10439, 0x0000, 0x0000, 0x0000 } },
- { 0x10412, { 0x1043A, 0x0000, 0x0000, 0x0000 } },
- { 0x10413, { 0x1043B, 0x0000, 0x0000, 0x0000 } },
- { 0x10414, { 0x1043C, 0x0000, 0x0000, 0x0000 } },
- { 0x10415, { 0x1043D, 0x0000, 0x0000, 0x0000 } },
- { 0x10416, { 0x1043E, 0x0000, 0x0000, 0x0000 } },
- { 0x10417, { 0x1043F, 0x0000, 0x0000, 0x0000 } },
- { 0x10418, { 0x10440, 0x0000, 0x0000, 0x0000 } },
- { 0x10419, { 0x10441, 0x0000, 0x0000, 0x0000 } },
- { 0x1041A, { 0x10442, 0x0000, 0x0000, 0x0000 } },
- { 0x1041B, { 0x10443, 0x0000, 0x0000, 0x0000 } },
- { 0x1041C, { 0x10444, 0x0000, 0x0000, 0x0000 } },
- { 0x1041D, { 0x10445, 0x0000, 0x0000, 0x0000 } },
- { 0x1041E, { 0x10446, 0x0000, 0x0000, 0x0000 } },
- { 0x1041F, { 0x10447, 0x0000, 0x0000, 0x0000 } },
- { 0x10420, { 0x10448, 0x0000, 0x0000, 0x0000 } },
- { 0x10421, { 0x10449, 0x0000, 0x0000, 0x0000 } },
- { 0x10422, { 0x1044A, 0x0000, 0x0000, 0x0000 } },
- { 0x10423, { 0x1044B, 0x0000, 0x0000, 0x0000 } },
- { 0x10424, { 0x1044C, 0x0000, 0x0000, 0x0000 } },
- { 0x10425, { 0x1044D, 0x0000, 0x0000, 0x0000 } },*/
+ { 0x10400, { 0xd801, 0xdc28, 0x0000, 0x0000 } },
+ { 0x10401, { 0xd801, 0xdc29, 0x0000, 0x0000 } },
+ { 0x10402, { 0xd801, 0xdc2A, 0x0000, 0x0000 } },
+ { 0x10403, { 0xd801, 0xdc2B, 0x0000, 0x0000 } },
+ { 0x10404, { 0xd801, 0xdc2C, 0x0000, 0x0000 } },
+ { 0x10405, { 0xd801, 0xdc2D, 0x0000, 0x0000 } },
+ { 0x10406, { 0xd801, 0xdc2E, 0x0000, 0x0000 } },
+ { 0x10407, { 0xd801, 0xdc2F, 0x0000, 0x0000 } },
+ { 0x10408, { 0xd801, 0xdc30, 0x0000, 0x0000 } },
+ { 0x10409, { 0xd801, 0xdc31, 0x0000, 0x0000 } },
+ { 0x1040A, { 0xd801, 0xdc32, 0x0000, 0x0000 } },
+ { 0x1040B, { 0xd801, 0xdc33, 0x0000, 0x0000 } },
+ { 0x1040C, { 0xd801, 0xdc34, 0x0000, 0x0000 } },
+ { 0x1040D, { 0xd801, 0xdc35, 0x0000, 0x0000 } },
+ { 0x1040E, { 0xd801, 0xdc36, 0x0000, 0x0000 } },
+ { 0x1040F, { 0xd801, 0xdc37, 0x0000, 0x0000 } },
+ { 0x10410, { 0xd801, 0xdc38, 0x0000, 0x0000 } },
+ { 0x10411, { 0xd801, 0xdc39, 0x0000, 0x0000 } },
+ { 0x10412, { 0xd801, 0xdc3A, 0x0000, 0x0000 } },
+ { 0x10413, { 0xd801, 0xdc3B, 0x0000, 0x0000 } },
+ { 0x10414, { 0xd801, 0xdc3C, 0x0000, 0x0000 } },
+ { 0x10415, { 0xd801, 0xdc3D, 0x0000, 0x0000 } },
+ { 0x10416, { 0xd801, 0xdc3E, 0x0000, 0x0000 } },
+ { 0x10417, { 0xd801, 0xdc3F, 0x0000, 0x0000 } },
+ { 0x10418, { 0xd801, 0xdc40, 0x0000, 0x0000 } },
+ { 0x10419, { 0xd801, 0xdc41, 0x0000, 0x0000 } },
+ { 0x1041A, { 0xd801, 0xdc42, 0x0000, 0x0000 } },
+ { 0x1041B, { 0xd801, 0xdc43, 0x0000, 0x0000 } },
+ { 0x1041C, { 0xd801, 0xdc44, 0x0000, 0x0000 } },
+ { 0x1041D, { 0xd801, 0xdc45, 0x0000, 0x0000 } },
+ { 0x1041E, { 0xd801, 0xdc46, 0x0000, 0x0000 } },
+ { 0x1041F, { 0xd801, 0xdc47, 0x0000, 0x0000 } },
+ { 0x10420, { 0xd801, 0xdc48, 0x0000, 0x0000 } },
+ { 0x10421, { 0xd801, 0xdc49, 0x0000, 0x0000 } },
+ { 0x10422, { 0xd801, 0xdc4A, 0x0000, 0x0000 } },
+ { 0x10423, { 0xd801, 0xdc4B, 0x0000, 0x0000 } },
+ { 0x10424, { 0xd801, 0xdc4C, 0x0000, 0x0000 } },
+ { 0x10425, { 0xd801, 0xdc4D, 0x0000, 0x0000 } },
{ 0x1D400, { 0x0061, 0x0000, 0x0000, 0x0000 } },
{ 0x1D401, { 0x0062, 0x0000, 0x0000, 0x0000 } },
{ 0x1D402, { 0x0063, 0x0000, 0x0000, 0x0000 } },
@@ -2355,17 +2354,23 @@ static void mapToLowerCase(QString *str, int from)
{
int N = sizeof(NameprepCaseFolding) / sizeof(NameprepCaseFolding[0]);
- QChar *d = 0;
+ ushort *d = 0;
for (int i = from; i < str->size(); ++i) {
- int uc = str->at(i).unicode();
+ uint uc = str->at(i).unicode();
if (uc < 0x80) {
if (uc <= 'Z' && uc >= 'A') {
- uc |= 0x20;
if (!d)
- d = str->data();
- d[i] = QChar(uc);
+ d = reinterpret_cast<ushort *>(str->data());
+ d[i] = (uc | 0x20);
}
} else {
+ if (QChar(uc).isHighSurrogate() && i < str->size() - 1) {
+ ushort low = str->at(i + 1).unicode();
+ if (QChar(low).isLowSurrogate()) {
+ uc = QChar::surrogateToUcs4(uc, low);
+ ++i;
+ }
+ }
const NameprepCaseFoldingEntry *entry = qBinaryFind(NameprepCaseFolding,
NameprepCaseFolding + N,
uc);
@@ -2374,23 +2379,26 @@ static void mapToLowerCase(QString *str, int from)
while (l < 4 && entry->mapping[l])
++l;
if (l > 1) {
- str->replace(i, 1, (const QChar *)&entry->mapping[0], l);
+ if (uc <= 0xffff)
+ str->replace(i, 1, reinterpret_cast<const QChar *>(&entry->mapping[0]), l);
+ else
+ str->replace(i-1, 2, reinterpret_cast<const QChar *>(&entry->mapping[0]), l);
d = 0;
} else {
if (!d)
- d = str->data();
- d[i] = QChar(entry->mapping[0]);
+ d = reinterpret_cast<ushort *>(str->data());
+ d[i] = entry->mapping[0];
}
}
}
}
}
-static bool isMappedToNothing(const QChar &ch)
+static bool isMappedToNothing(uint uc)
{
- if (ch.unicode() < 0xad)
+ if (uc < 0xad)
return false;
- switch (ch.unicode()) {
+ switch (uc) {
case 0x00AD: case 0x034F: case 0x1806: case 0x180B: case 0x180C: case 0x180D:
case 0x200B: case 0x200C: case 0x200D: case 0x2060: case 0xFE00: case 0xFE01:
case 0xFE02: case 0xFE03: case 0xFE04: case 0xFE05: case 0xFE06: case 0xFE07:
@@ -2409,66 +2417,72 @@ static void stripProhibitedOutput(QString *str, int from)
const ushort *in = out;
const ushort *end = (ushort *)str->data() + str->size();
while (in < end) {
- ushort uc = *in;
- if (uc < 0x80 ||
- !(uc <= 0x009F
- || uc == 0x00A0
- || uc == 0x0340
- || uc == 0x0341
- || uc == 0x06DD
- || uc == 0x070F
- || uc == 0x1680
- || uc == 0x180E
- || (uc >= 0x2000 && uc <= 0x200B)
- || uc == 0x200C
- || uc == 0x200D
- || uc == 0x200E
- || uc == 0x200F
- || (uc >= 0x2028 && uc <= 0x202F)
- || uc == 0x205F
- || (uc >= 0x2060 && uc <= 0x2063)
- || uc == 0x206A
- || (uc >= 0x206A && uc <= 0x206F)
- || (uc >= 0x2FF0 && uc <= 0x2FFB)
- || uc == 0x3000
- || (uc >= 0xD800 && uc <= 0xDFFF)
- || (uc >= 0xE000 && uc <= 0xF8FF)
- || (uc >= 0xFDD0 && uc <= 0xFDEF)
- || uc == 0xFEFF
- || (uc >= 0xFFF9 && uc <= 0xFFFC)
- || (uc >= 0xFFFA && (uc <= 0xFFFE || uc == 0xFFFF))
- /* ### Add NAMEPREP support for surrogates
- || uc == 0xE0001
- || (uc >= 0x2FFFE && uc <= 0x2FFFF)
- || (uc >= 0x1D173 && uc <= 0x1D17A)
- || (uc >= 0x1FFFE && uc <= 0x1FFFF)
- || (uc >= 0x3FFFE && uc <= 0x3FFFF)
- || (uc >= 0x4FFFE && uc <= 0x4FFFF)
- || (uc >= 0x5FFFE && uc <= 0x5FFFF)
- || (uc >= 0x6FFFE && uc <= 0x6FFFF)
- || (uc >= 0x7FFFE && uc <= 0x7FFFF)
- || (uc >= 0x8FFFE && uc <= 0x8FFFF)
- || (uc >= 0x9FFFE && uc <= 0x9FFFF)
- || (uc >= 0xAFFFE && uc <= 0xAFFFF)
- || (uc >= 0xBFFFE && uc <= 0xBFFFF)
- || (uc >= 0xCFFFE && uc <= 0xCFFFF)
- || (uc >= 0xDFFFE && uc <= 0xDFFFF)
- || (uc >= 0xE0020 && uc <= 0xE007F)
- || (uc >= 0xEFFFE && uc <= 0xEFFFF)
- || (uc >= 0xF0000 && uc <= 0xFFFFD)
- || (uc >= 0xFFFFE && uc <= 0xFFFFF)
- || (uc >= 0x100000 && uc <= 0x10FFFD)
- || (uc >= 0x10FFFE && uc <= 0x10FFFF)*/))
- *out++ = *in;
+ uint uc = *in;
+ if (QChar(uc).isHighSurrogate() && in < end - 1) {
+ ushort low = *(in + 1);
+ if (QChar(low).isLowSurrogate()) {
+ ++in;
+ uc = QChar::surrogateToUcs4(uc, low);
+ }
+ }
+ if (uc <= 0xFFFF) {
+ if (uc < 0x80 ||
+ !(uc <= 0x009F
+ || uc == 0x00A0
+ || uc == 0x0340
+ || uc == 0x0341
+ || uc == 0x06DD
+ || uc == 0x070F
+ || uc == 0x1680
+ || uc == 0x180E
+ || (uc >= 0x2000 && uc <= 0x200F)
+ || (uc >= 0x2028 && uc <= 0x202F)
+ || uc == 0x205F
+ || (uc >= 0x2060 && uc <= 0x2063)
+ || (uc >= 0x206A && uc <= 0x206F)
+ || (uc >= 0x2FF0 && uc <= 0x2FFB)
+ || uc == 0x3000
+ || (uc >= 0xD800 && uc <= 0xDFFF)
+ || (uc >= 0xE000 && uc <= 0xF8FF)
+ || (uc >= 0xFDD0 && uc <= 0xFDEF)
+ || uc == 0xFEFF
+ || (uc >= 0xFFF9 && uc <= 0xFFFF))) {
+ *out++ = *in;
+ }
+ } else {
+ if (!((uc >= 0x1D173 && uc <= 0x1D17A)
+ || (uc >= 0x1FFFE && uc <= 0x1FFFF)
+ || (uc >= 0x2FFFE && uc <= 0x2FFFF)
+ || (uc >= 0x3FFFE && uc <= 0x3FFFF)
+ || (uc >= 0x4FFFE && uc <= 0x4FFFF)
+ || (uc >= 0x5FFFE && uc <= 0x5FFFF)
+ || (uc >= 0x6FFFE && uc <= 0x6FFFF)
+ || (uc >= 0x7FFFE && uc <= 0x7FFFF)
+ || (uc >= 0x8FFFE && uc <= 0x8FFFF)
+ || (uc >= 0x9FFFE && uc <= 0x9FFFF)
+ || (uc >= 0xAFFFE && uc <= 0xAFFFF)
+ || (uc >= 0xBFFFE && uc <= 0xBFFFF)
+ || (uc >= 0xCFFFE && uc <= 0xCFFFF)
+ || (uc >= 0xDFFFE && uc <= 0xDFFFF)
+ || uc == 0xE0001
+ || (uc >= 0xE0020 && uc <= 0xE007F)
+ || (uc >= 0xEFFFE && uc <= 0xEFFFF)
+ || (uc >= 0xF0000 && uc <= 0xFFFFD)
+ || (uc >= 0xFFFFE && uc <= 0xFFFFF)
+ || (uc >= 0x100000 && uc <= 0x10FFFD)
+ || (uc >= 0x10FFFE && uc <= 0x10FFFF))) {
+ *out++ = QChar::highSurrogate(uc);
+ *out++ = QChar::lowSurrogate(uc);
+ }
+ }
++in;
}
if (in != out)
str->truncate(out - str->utf16());
}
-static bool isBidirectionalRorAL(const QChar &c)
+static bool isBidirectionalRorAL(uint uc)
{
- ushort uc = c.unicode();
if (uc < 0x5b0)
return false;
return uc == 0x05BE
@@ -2507,9 +2521,8 @@ static bool isBidirectionalRorAL(const QChar &c)
|| (uc >= 0xFE76 && uc <= 0xFEFC);
}
-static bool isBidirectionalL(const QChar &ch)
+static bool isBidirectionalL(uint uc)
{
- ushort uc = ch.unicode();
if (uc < 0xaa)
return (uc >= 0x0041 && uc <= 0x005A)
|| (uc >= 0x0061 && uc <= 0x007A);
@@ -2874,8 +2887,7 @@ static bool isBidirectionalL(const QChar &ch)
return true;
}
- /* ### Add NAMEPREP support for surrogates
- || (uc >= 0x10300 && uc <= 0x1031E)
+ if ((uc >= 0x10300 && uc <= 0x1031E)
|| (uc >= 0x10320 && uc <= 0x10323)
|| (uc >= 0x10330 && uc <= 0x1034A)
|| (uc >= 0x10400 && uc <= 0x10425)
@@ -2911,7 +2923,9 @@ static bool isBidirectionalL(const QChar &ch)
|| (uc >= 0x20000 && uc <= 0x2A6D6)
|| (uc >= 0x2F800 && uc <= 0x2FA1D)
|| (uc >= 0xF0000 && uc <= 0xFFFFD)
- || (uc >= 0x100000 && uc <= 0x10FFFD)*/
+ || (uc >= 0x100000 && uc <= 0x10FFFD)) {
+ return true;
+ }
return false;
}
@@ -2944,13 +2958,37 @@ void qt_nameprep(QString *source, int from)
return; // everything was mapped easily (lowercased, actually)
int firstNonAscii = out - src;
+ // Characters unassigned in Unicode 3.2 are not allowed in "stored string" scheme
+ // but allowed in "query" scheme
+ // (Table A.1)
+ const bool isUnassignedAllowed = false; // ###
// Characters commonly mapped to nothing are simply removed
// (Table B.1)
const QChar *in = out;
- while (in < e) {
- if (!isMappedToNothing(*in))
- *out++ = *in;
- ++in;
+ for ( ; in < e; ++in) {
+ uint uc = in->unicode();
+ if (QChar(uc).isHighSurrogate() && in < e - 1) {
+ ushort low = in[1].unicode();
+ if (QChar(low).isLowSurrogate()) {
+ ++in;
+ uc = QChar::surrogateToUcs4(uc, low);
+ }
+ }
+ if (!isUnassignedAllowed) {
+ QChar::UnicodeVersion version = QChar::unicodeVersion(uc);
+ if (version == QChar::Unicode_Unassigned || version > QChar::Unicode_3_2) {
+ source->resize(from); // not allowed, clear the label
+ return;
+ }
+ }
+ if (!isMappedToNothing(uc)) {
+ if (uc <= 0xFFFF) {
+ *out++ = *in;
+ } else {
+ *out++ = QChar::highSurrogate(uc);
+ *out++ = QChar::lowSurrogate(uc);
+ }
+ }
}
if (out != in)
source->truncate(out - src);
@@ -2961,7 +2999,8 @@ void qt_nameprep(QString *source, int from)
// Normalize to Unicode 3.2 form KC
extern void qt_string_normalize(QString *data, QString::NormalizationForm mode,
QChar::UnicodeVersion version, int from);
- qt_string_normalize(source, QString::NormalizationForm_KC, QChar::Unicode_3_2, firstNonAscii);
+ qt_string_normalize(source, QString::NormalizationForm_KC, QChar::Unicode_3_2,
+ firstNonAscii > from ? firstNonAscii - 1 : from);
// Strip prohibited output
stripProhibitedOutput(source, firstNonAscii);
@@ -2972,14 +3011,22 @@ void qt_nameprep(QString *source, int from)
src = source->data();
e = src + source->size();
for (in = src + from; in < e && (!containsLCat || !containsRandALCat); ++in) {
- if (isBidirectionalL(*in))
+ uint uc = in->unicode();
+ if (QChar(uc).isHighSurrogate() && in < e - 1) {
+ ushort low = in[1].unicode();
+ if (QChar(low).isLowSurrogate()) {
+ ++in;
+ uc = QChar::surrogateToUcs4(uc, low);
+ }
+ }
+ if (isBidirectionalL(uc))
containsLCat = true;
- else if (isBidirectionalRorAL(*in))
+ else if (isBidirectionalRorAL(uc))
containsRandALCat = true;
}
if (containsRandALCat) {
- if (containsLCat || (!isBidirectionalRorAL(src[from])
- || !isBidirectionalRorAL(e[-1])))
+ if (containsLCat || (!isBidirectionalRorAL(src[from].unicode())
+ || !isBidirectionalRorAL(e[-1].unicode())))
source->resize(from); // not allowed, clear the label
}
}
@@ -6024,19 +6071,22 @@ bool QUrl::isDetached() const
/*!
- Returns a QUrl representation of \a localFile, interpreted as a
- local file.
+ Returns a QUrl representation of \a localFile, interpreted as a local
+ file. This function accepts paths separated by slashes as well as the
+ native separator for this platform.
- \sa toLocalFile()
+ This function also accepts paths with a doubled leading slash (or
+ backslash) to indicate a remote file, as in
+ "//servername/path/to/file.txt". Note that only certain platforms can
+ actually open this file using QFile::open().
+
+ \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators
*/
QUrl QUrl::fromLocalFile(const QString &localFile)
{
QUrl url;
url.setScheme(QLatin1String("file"));
- QString deslashified = localFile;
- deslashified.replace(QLatin1Char('\\'), QLatin1Char('/'));
-
-
+ QString deslashified = QDir::fromNativeSeparators(localFile);
// magic for drives on windows
if (deslashified.length() > 1 && deslashified.at(1) == QLatin1Char(':') && deslashified.at(0) != QLatin1Char('/')) {
@@ -6055,35 +6105,61 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
}
/*!
- Returns the path of this URL formatted as a local file path.
+ Returns the path of this URL formatted as a local file path. The path
+ returned will use forward slashes, even if it was originally created
+ from one with backslashes.
- \sa fromLocalFile()
+ If this URL contains a non-empty hostname, it will be encoded in the
+ returned value in the form found on SMB networks (for example,
+ "//servername/path/to/file.txt").
+
+ \sa fromLocalFile(), isLocalFile()
*/
QString QUrl::toLocalFile() const
{
- if (!d) return QString();
- if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
+ // the call to isLocalFile() also ensures that we're parsed
+ if (!isLocalFile())
+ return QString();
QString tmp;
QString ourPath = path();
- if (d->scheme.isEmpty() || QString::compare(d->scheme, QLatin1String("file"), Qt::CaseInsensitive) == 0) {
- // magic for shared drive on windows
- if (!d->host.isEmpty()) {
- tmp = QLatin1String("//") + d->host + (ourPath.length() > 0 && ourPath.at(0) != QLatin1Char('/')
- ? QLatin1Char('/') + ourPath : ourPath);
- } else {
- tmp = ourPath;
- // magic for drives on windows
- if (ourPath.length() > 2 && ourPath.at(0) == QLatin1Char('/') && ourPath.at(2) == QLatin1Char(':'))
- tmp.remove(0, 1);
- }
+ // magic for shared drive on windows
+ if (!d->host.isEmpty()) {
+ tmp = QLatin1String("//") + d->host + (ourPath.length() > 0 && ourPath.at(0) != QLatin1Char('/')
+ ? QLatin1Char('/') + ourPath : ourPath);
+ } else {
+ tmp = ourPath;
+ // magic for drives on windows
+ if (ourPath.length() > 2 && ourPath.at(0) == QLatin1Char('/') && ourPath.at(2) == QLatin1Char(':'))
+ tmp.remove(0, 1);
}
return tmp;
}
/*!
+ \since 4.7
+ Returns true if this URL is pointing to a local file path. A URL is a
+ local file path if the scheme is "file".
+
+ Note that this function considers URLs with hostnames to be local file
+ paths, even if the eventual file path cannot be opened with
+ QFile::open().
+
+ \sa fromLocalFile(), toLocalFile()
+*/
+bool QUrl::isLocalFile() const
+{
+ if (!d) return false;
+ if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
+
+ if (d->scheme.compare(QLatin1String("file"), Qt::CaseInsensitive) != 0)
+ return false; // not file
+ return true;
+}
+
+/*!
Returns true if this URL is a parent of \a childUrl. \a childUrl is a child
of this URL if the two URLs share the same scheme and authority,
and this URL's path is a parent of the path of \a childUrl.
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 6f8331a3f3..563be5fd19 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -94,6 +94,10 @@ public:
#ifndef QT_NO_URL_CAST_FROM_STRING
QUrl &operator =(const QString &url);
#endif
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QUrl &operator=(QUrl &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
~QUrl();
void setUrl(const QString &url);
@@ -183,6 +187,7 @@ public:
static QUrl fromLocalFile(const QString &localfile);
QString toLocalFile() const;
+ bool isLocalFile() const;
QString toString(FormattingOptions options = None) const;
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 9a99ea1c57..4fc97923d5 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -532,7 +532,7 @@ bool QAbstractItemModelPrivate::variantLessThan(const QVariant &v1, const QVaria
case 1: //floating point
return v1.toReal() < v2.toReal();
default:
- return v1.toString() < v2.toString();
+ return v1.toString().localeAwareCompare(v2.toString()) < 0;
}
}
diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp
index 66296b045c..df1c1ef648 100644
--- a/src/corelib/kernel/qcore_symbian_p.cpp
+++ b/src/corelib/kernel/qcore_symbian_p.cpp
@@ -61,7 +61,8 @@ Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString)
#else
TPtrC16 ptr(qt_QString2TPtrC(aString));
#endif
- buffer = q_check_ptr(HBufC::New(ptr.Length()));
+ buffer = HBufC::New(ptr.Length());
+ Q_CHECK_PTR(buffer);
buffer->Des().Copy(ptr);
return buffer;
}
@@ -81,8 +82,9 @@ QHBufC::QHBufC()
}
QHBufC::QHBufC(const QHBufC &src)
- : m_hBufC(q_check_ptr(src.m_hBufC->Alloc()))
+ : m_hBufC(src.m_hBufC->Alloc())
{
+ Q_CHECK_PTR(m_hBufC);
}
/*!
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index d3f399b754..e967884241 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -122,6 +122,11 @@ static SystemDriveFunc PtrGetSystemDrive=0;
extern QString qAppFileName();
#endif
+int QCoreApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0
+#if defined(QT3_SUPPORT)
+bool QCoreApplicationPrivate::useQt3Support = true;
+#endif
+
#if !defined(Q_OS_WIN)
#ifdef Q_OS_MAC
QString QCoreApplicationPrivate::macMenuBarName()
@@ -263,10 +268,14 @@ struct QCoreApplicationData {
Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
-QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv)
+QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
: QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
in_exec(false), aboutToQuitEmitted(false)
{
+ app_compile_version = flags & 0xffffff;
+#if defined(QT3_SUPPORT)
+ useQt3Support = !(flags & 0x01000000);
+#endif
static const char *const empty = "";
if (argc == 0 || argv == 0) {
argc = 0;
@@ -511,7 +520,7 @@ void QCoreApplication::flush()
one valid character string.
*/
QCoreApplication::QCoreApplication(int &argc, char **argv)
- : QObject(*new QCoreApplicationPrivate(argc, argv))
+ : QObject(*new QCoreApplicationPrivate(argc, argv, 0x040000))
{
init();
QCoreApplicationPrivate::eventDispatcher->startingUp();
@@ -527,6 +536,25 @@ QCoreApplication::QCoreApplication(int &argc, char **argv)
#endif
}
+QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal)
+: QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
+{
+ init();
+ QCoreApplicationPrivate::eventDispatcher->startingUp();
+#if defined(Q_OS_SYMBIAN)
+#ifndef QT_NO_LIBRARY
+ // Refresh factoryloader, as text codecs are requested during lib path
+ // resolving process and won't be therefore properly loaded.
+ // Unknown if this is symbian specific issue.
+ QFactoryLoader::refreshAll();
+#endif
+#ifndef QT_NO_SYSTEMLOCALE
+ d_func()->symbianInit();
+#endif
+#endif //Q_OS_SYMBIAN
+}
+
+
// ### move to QCoreApplicationPrivate constructor?
void QCoreApplication::init()
{
@@ -805,11 +833,6 @@ bool QCoreApplication::notify(QObject *receiver, QEvent *event)
d->checkReceiverThread(receiver);
#endif
-#ifdef QT3_SUPPORT
- if (event->type() == QEvent::ChildRemoved && !receiver->d_func()->pendingChildInsertedEvents.isEmpty())
- receiver->d_func()->removePendingChildInsertedEvents(static_cast<QChildEvent *>(event)->child());
-#endif // QT3_SUPPORT
-
return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
}
@@ -1019,6 +1042,7 @@ int QCoreApplication::exec()
return returnCode;
}
+
/*!
Tells the application to exit with a return code.
@@ -1475,7 +1499,7 @@ void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
--pe.receiver->d_func()->postedEvents;
#ifdef QT3_SUPPORT
if (pe.event->type() == QEvent::ChildInsertedRequest)
- pe.receiver->d_func()->removePendingChildInsertedEvents(0);
+ pe.receiver->d_func()->pendingChildInsertedEvents.clear();
#endif
pe.event->posted = false;
events.append(pe.event);
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index d87103e2a4..f1c7c267de 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -78,7 +78,23 @@ class Q_CORE_EXPORT QCoreApplication : public QObject
Q_DECLARE_PRIVATE(QCoreApplication)
public:
- QCoreApplication(int &argc, char **argv);
+ enum { ApplicationFlags = QT_VERSION
+#if !defined(QT3_SUPPORT)
+ | 0x01000000
+#endif
+ };
+
+#if defined(QT_BUILD_CORE_LIB) || defined(qdoc)
+ QCoreApplication(int &argc, char **argv); // ### Qt5 remove
+#endif
+#if !defined(qdoc)
+ QCoreApplication(int &argc, char **argv, int
+#if !defined(QT_BUILD_CORE_LIB)
+ = ApplicationFlags
+#endif
+ );
+#endif
+
~QCoreApplication();
#ifdef QT_DEPRECATED
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index e066137731..2355c379c2 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -75,7 +75,7 @@ class Q_CORE_EXPORT QCoreApplicationPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QCoreApplication)
public:
- QCoreApplicationPrivate(int &aargc, char **aargv);
+ QCoreApplicationPrivate(int &aargc, char **aargv, uint flags);
~QCoreApplicationPrivate();
bool sendThroughApplicationEventFilters(QObject *, QEvent *);
@@ -129,6 +129,10 @@ public:
static uint attribs;
static inline bool testAttribute(uint flag) { return attribs & (1 << flag); }
+ static int app_compile_version;
+#if defined(QT3_SUPPORT)
+ static bool useQt3Support;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index 5cc6ae3c33..02736dd5ae 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -1013,7 +1013,8 @@ bool QEventDispatcherSymbian::hasPendingEvents()
void QEventDispatcherSymbian::registerSocketNotifier ( QSocketNotifier * notifier )
{
- QSocketActiveObject *socketAO = q_check_ptr(new QSocketActiveObject(this, notifier));
+ QSocketActiveObject *socketAO = new QSocketActiveObject(this, notifier);
+ Q_CHECK_PTR(socketAO);
m_notifiers.insert(notifier, socketAO);
selectThread().requestSocketEvents(notifier, &socketAO->iStatus);
}
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 9854e68bca..ceb2a9c9c8 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -266,7 +266,25 @@ QObject *QMetaObject::cast(QObject *obj) const
const QMetaObject *m = obj->metaObject();
do {
if (m == this)
- return const_cast<QObject*>(obj);
+ return obj;
+ } while ((m = m->d.superdata));
+ }
+ return 0;
+}
+
+/*!
+ \internal
+
+ Returns \a obj if object \a obj inherits from this
+ meta-object; otherwise returns 0.
+*/
+const QObject *QMetaObject::cast(const QObject *obj) const
+{
+ if (obj) {
+ const QMetaObject *m = obj->metaObject();
+ do {
+ if (m == this)
+ return obj;
} while ((m = m->d.superdata));
}
return 0;
@@ -1558,6 +1576,12 @@ bool QMetaMethod::invoke(QObject *object,
: Qt::QueuedConnection;
}
+#ifdef QT_NO_THREAD
+ if (connectionType == Qt::BlockingQueuedConnection) {
+ connectionType = Qt::DirectConnection;
+ }
+#endif
+
// invoke!
void *param[] = {
returnValue.data(),
@@ -1576,7 +1600,7 @@ bool QMetaMethod::invoke(QObject *object,
int methodIndex = ((handle - priv(mobj->d.data)->methodData) / 5) + mobj->methodOffset();
if (connectionType == Qt::DirectConnection) {
return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, methodIndex, param) < 0;
- } else {
+ } else if (connectionType == Qt::QueuedConnection) {
if (returnValue.data()) {
qWarning("QMetaMethod::invoke: Unable to invoke methods with return values in "
"queued connections");
@@ -1609,40 +1633,21 @@ bool QMetaMethod::invoke(QObject *object,
}
}
- if (connectionType == Qt::QueuedConnection) {
- QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex,
- 0,
- -1,
- nargs,
- types,
- args));
- } else {
- if (currentThread == objectThread) {
- qWarning("QMetaMethod::invoke: Dead lock detected in "
- "BlockingQueuedConnection: Receiver is %s(%p)",
- mobj->className(), object);
- }
+ QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex,
+ 0, -1, nargs, types, args));
+ } else { // blocking queued connection
+#ifndef QT_NO_THREAD
+ if (currentThread == objectThread) {
+ qWarning("QMetaMethod::invoke: Dead lock detected in "
+ "BlockingQueuedConnection: Receiver is %s(%p)",
+ mobj->className(), object);
+ }
- // blocking queued connection
-#ifdef QT_NO_THREAD
- QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex,
- 0,
- -1,
- nargs,
- types,
- args));
-#else
- QSemaphore semaphore;
- QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex,
- 0,
- -1,
- nargs,
- types,
- args,
- &semaphore));
- semaphore.acquire();
+ QSemaphore semaphore;
+ QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex,
+ 0, -1, 0, 0, param, &semaphore));
+ semaphore.acquire();
#endif // QT_NO_THREAD
- }
}
return true;
}
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index b700351f02..8124487315 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -138,6 +138,8 @@ private:
const QMetaObject *mobj;
uint handle;
friend struct QMetaObject;
+ friend struct QMetaObjectPrivate;
+ friend class QObject;
};
Q_DECLARE_TYPEINFO(QMetaMethod, Q_MOVABLE_TYPE);
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 4a03874f39..40b87150a4 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -131,6 +131,8 @@ struct QMetaObjectPrivate
#ifndef QT_NO_QOBJECT
//defined in qobject.cpp
enum DisconnectType { DisconnectAll, DisconnectOne };
+ static void memberIndexes(const QObject *obj, const QMetaMethod &member,
+ int *signalIndex, int *methodIndex);
static bool connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index,
int type = 0, int *types = 0);
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index fef02cfe41..bb77d2c105 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -311,6 +311,7 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ
QT_ADD_STATIC_METATYPE("long long", QMetaType::LongLong),
QT_ADD_STATIC_METATYPE("unsigned long long", QMetaType::ULongLong),
QT_ADD_STATIC_METATYPE("qint8", QMetaType::Char),
+ QT_ADD_STATIC_METATYPE("signed char", QMetaType::Char),
QT_ADD_STATIC_METATYPE("quint8", QMetaType::UChar),
QT_ADD_STATIC_METATYPE("qint16", QMetaType::Short),
QT_ADD_STATIC_METATYPE("quint16", QMetaType::UShort),
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index e16ffe8b6e..eebb3dbc62 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -353,6 +353,7 @@ Q_DECLARE_BUILTIN_METATYPE(QChar, QChar)
Q_DECLARE_BUILTIN_METATYPE(long, Long)
Q_DECLARE_BUILTIN_METATYPE(short, Short)
Q_DECLARE_BUILTIN_METATYPE(char, Char)
+Q_DECLARE_BUILTIN_METATYPE(signed char, Char)
Q_DECLARE_BUILTIN_METATYPE(ulong, ULong)
Q_DECLARE_BUILTIN_METATYPE(ushort, UShort)
Q_DECLARE_BUILTIN_METATYPE(uchar, UChar)
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 8330e474a9..ceffa66c8b 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -149,9 +149,11 @@ QObjectPrivate::QObjectPrivate(int version)
postedEvents = 0;
extraData = 0;
connectedSignals[0] = connectedSignals[1] = 0;
- inEventHandler = false;
inThreadChangeEvent = false;
+#ifdef QT_JAMBI_BUILD
+ inEventHandler = false;
deleteWatch = 0;
+#endif
metaObject = 0;
hasGuards = false;
}
@@ -159,8 +161,10 @@ QObjectPrivate::QObjectPrivate(int version)
QObjectPrivate::~QObjectPrivate()
{
delete static_cast<QAbstractDynamicMetaObject*>(metaObject);
+#ifdef QT_JAMBI_BUILD
if (deleteWatch)
*deleteWatch = 1;
+#endif
#ifndef QT_NO_USERDATA
if (extraData)
qDeleteAll(extraData->userData);
@@ -169,6 +173,7 @@ QObjectPrivate::~QObjectPrivate()
}
+#ifdef QT_JAMBI_BUILD
int *QObjectPrivate::setDeleteWatch(QObjectPrivate *d, int *w) {
int *old = d->deleteWatch;
d->deleteWatch = w;
@@ -183,18 +188,15 @@ void QObjectPrivate::resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int dele
if (oldWatch)
*oldWatch = deleteWatch;
}
-
-
-
-
+#endif
#ifdef QT3_SUPPORT
void QObjectPrivate::sendPendingChildInsertedEvents()
{
Q_Q(QObject);
for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {
- QObject *c = pendingChildInsertedEvents.at(i);
- if (!c)
+ QObject *c = pendingChildInsertedEvents.at(i).data();
+ if (!c || c->parent() != q)
continue;
QChildEvent childEvent(QEvent::ChildInserted, c);
QCoreApplication::sendEvent(q, &childEvent);
@@ -202,26 +204,6 @@ void QObjectPrivate::sendPendingChildInsertedEvents()
pendingChildInsertedEvents.clear();
}
-void QObjectPrivate::removePendingChildInsertedEvents(QObject *child)
-{
- if (!child) {
- pendingChildInsertedEvents.clear();
- return;
- }
-
- // the QObject destructor calls QObject::removeChild, which calls
- // QCoreApplication::sendEvent() directly. this can happen while the event
- // loop is in the middle of posting events, and when we get here, we may
- // not have any more posted events for this object.
-
- // if this is a child remove event and the child insert hasn't
- // been dispatched yet, kill that insert
- for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {
- QObject *&c = pendingChildInsertedEvents[i];
- if (c == child)
- c = 0;
- }
-}
#endif
@@ -476,11 +458,6 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o)
*/
void QObjectPrivate::clearGuards(QObject *object)
{
- QObjectPrivate *priv = QObjectPrivate::get(object);
-
- if (!priv->hasGuards)
- return;
-
GuardHash *hash = 0;
QMutex *mutex = 0;
QT_TRY {
@@ -515,12 +492,14 @@ QMetaCallEvent::QMetaCallEvent(int id, const QObject *sender, int signalId,
*/
QMetaCallEvent::~QMetaCallEvent()
{
- for (int i = 0; i < nargs_; ++i) {
- if (types_[i] && args_[i])
- QMetaType::destroy(types_[i], args_[i]);
+ if (types_) {
+ for (int i = 0; i < nargs_; ++i) {
+ if (types_[i] && args_[i])
+ QMetaType::destroy(types_[i], args_[i]);
+ }
+ qFree(types_);
+ qFree(args_);
}
- if (types_) qFree(types_);
- if (args_) qFree(args_);
#ifndef QT_NO_THREAD
if (semaphore_)
semaphore_->release();
@@ -730,13 +709,15 @@ QObject::QObject(QObject *parent)
d_ptr->q_ptr = this;
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
d->threadData->ref();
- QT_TRY {
- if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
- parent = 0;
- setParent(parent);
- } QT_CATCH(...) {
- d->threadData->deref();
- QT_RETHROW;
+ if (parent) {
+ QT_TRY {
+ if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
+ parent = 0;
+ setParent(parent);
+ } QT_CATCH(...) {
+ d->threadData->deref();
+ QT_RETHROW;
+ }
}
qt_addObject(this);
}
@@ -755,9 +736,11 @@ QObject::QObject(QObject *parent, const char *name)
qt_addObject(d_ptr->q_ptr = this);
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
d->threadData->ref();
- if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
- parent = 0;
- setParent(parent);
+ if (parent) {
+ if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
+ parent = 0;
+ setParent(parent);
+ }
setObjectName(QString::fromAscii(name));
}
#endif
@@ -771,21 +754,23 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent)
d_ptr->q_ptr = this;
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
d->threadData->ref();
- QT_TRY {
- if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
- parent = 0;
- if (d->isWidget) {
- if (parent) {
- d->parent = parent;
- d->parent->d_func()->children.append(this);
+ if (parent) {
+ QT_TRY {
+ if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
+ parent = 0;
+ if (d->isWidget) {
+ if (parent) {
+ d->parent = parent;
+ d->parent->d_func()->children.append(this);
+ }
+ // no events sent here, this is done at the end of the QWidget constructor
+ } else {
+ setParent(parent);
}
- // no events sent here, this is done at the end of the QWidget constructor
- } else {
- setParent(parent);
+ } QT_CATCH(...) {
+ d->threadData->deref();
+ QT_RETHROW;
}
- } QT_CATCH(...) {
- d->threadData->deref();
- QT_RETHROW;
}
qt_addObject(this);
}
@@ -820,7 +805,7 @@ QObject::~QObject()
d->wasDeleted = true;
d->blockSig = 0; // unblock signals so we always emit destroyed()
- if (!d->isWidget) {
+ if (d->hasGuards && !d->isWidget) {
// set all QPointers for this object to zero - note that
// ~QWidget() does this for us, so we don't have to do it twice
QObjectPrivate::clearGuards(this);
@@ -838,22 +823,16 @@ QObject::~QObject()
delete d->sharedRefcount;
}
- QT_TRY {
- emit destroyed(this);
- } QT_CATCH(...) {
- // all the signal/slots connections are still in place - if we don't
- // quit now, we will crash pretty soon.
- qWarning("Detected an unexpected exception in ~QObject while emitting destroyed().");
-#if defined(Q_BUILD_INTERNAL) && !defined(QT_NO_EXCEPTIONS)
- struct AutotestException : public std::exception
- {
- const char *what() const throw() { return "autotest swallow"; }
- } autotestException;
- // throw autotestException;
-#else
- QT_RETHROW;
-#endif
+ if (d->isSignalConnected(0)) {
+ QT_TRY {
+ emit destroyed(this);
+ } QT_CATCH(...) {
+ // all the signal/slots connections are still in place - if we don't
+ // quit now, we will crash pretty soon.
+ qWarning("Detected an unexpected exception in ~QObject while emitting destroyed().");
+ QT_RETHROW;
+ }
}
if (d->declarativeData)
@@ -891,7 +870,7 @@ QObject::~QObject()
if (c->next) c->next->prev = c->prev;
}
if (needToUnlock)
- m->unlock();
+ m->unlockInline();
connectionList.first = c->nextConnectionList;
delete c;
@@ -915,7 +894,7 @@ QObject::~QObject()
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
//the node has maybe been removed while the mutex was unlocked in relock?
if (!node || node->sender != sender) {
- m->unlock();
+ m->unlockInline();
continue;
}
node->receiver = 0;
@@ -925,7 +904,7 @@ QObject::~QObject()
node = node->next;
if (needToUnlock)
- m->unlock();
+ m->unlockInline();
}
}
@@ -935,12 +914,6 @@ QObject::~QObject()
d->threadData->eventDispatcher->unregisterTimers(this);
}
-#ifdef QT3_SUPPORT
- d->pendingChildInsertedEvents.clear();
-#endif
-
- d->eventFilters.clear();
-
if (!d->children.isEmpty())
d->deleteChildren();
@@ -1196,7 +1169,9 @@ bool QObject::event(QEvent *e)
case QEvent::MetaCall:
{
+#ifdef QT_JAMBI_BUILD
d_func()->inEventHandler = false;
+#endif
QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
QObjectPrivate::Sender currentSender;
currentSender.sender = const_cast<QObject*>(mce->sender());
@@ -1514,11 +1489,14 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
currentSender->ref = 0;
currentSender = 0;
+#ifdef QT_JAMBI_BUILD
// the current event thread also shouldn't restore the delete watch
inEventHandler = false;
+
if (deleteWatch)
*deleteWatch = 1;
deleteWatch = 0;
+#endif
// set new thread data
targetData->ref();
@@ -1768,11 +1746,7 @@ QObjectList QObject::queryList(const char *inheritsClass,
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 11
- \warning This function is not available with MSVC 6. Use
- qFindChild() instead if you need to support that version of the
- compiler.
-
- \sa findChildren(), qFindChild()
+ \sa findChildren()
*/
/*!
@@ -1792,11 +1766,7 @@ QObjectList QObject::queryList(const char *inheritsClass,
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 13
- \warning This function is not available with MSVC 6. Use
- qFindChildren() instead if you need to support that version of the
- compiler.
-
- \sa findChild(), qFindChildren()
+ \sa findChild()
*/
/*!
@@ -1807,20 +1777,19 @@ QObjectList QObject::queryList(const char *inheritsClass,
and that have names matching the regular expression \a regExp,
or an empty list if there are no such objects.
The search is performed recursively.
-
- \warning This function is not available with MSVC 6. Use
- qFindChildren() instead if you need to support that version of the
- compiler.
*/
/*!
\fn T qFindChild(const QObject *obj, const QString &name)
\relates QObject
+ \obsolete
This function is equivalent to
- \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name). It is
- provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QObject::findChild()
*/
@@ -1828,11 +1797,14 @@ QObjectList QObject::queryList(const char *inheritsClass,
/*!
\fn QList<T> qFindChildren(const QObject *obj, const QString &name)
\relates QObject
+ \obsolete
This function is equivalent to
- \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name). It is
- provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QObject::findChildren()
*/
@@ -1843,9 +1815,13 @@ QObjectList QObject::queryList(const char *inheritsClass,
\overload qFindChildren()
This function is equivalent to
- \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a regExp). It is
- provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a regExp).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
+
+ \sa QObject::findChildren()
*/
/*!
@@ -1855,9 +1831,11 @@ QObjectList QObject::queryList(const char *inheritsClass,
\overload qFindChildren()
This function is equivalent to
- \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name). It is
- provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QObject::findChild()
*/
@@ -1869,9 +1847,11 @@ QObjectList QObject::queryList(const char *inheritsClass,
\overload qFindChildren()
This function is equivalent to
- \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name). It is
- provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QObject::findChildren()
*/
@@ -1991,12 +1971,14 @@ void QObjectPrivate::setParent_helper(QObject *o)
QChildEvent e(QEvent::ChildAdded, q);
QCoreApplication::sendEvent(parent, &e);
#ifdef QT3_SUPPORT
- if (parent->d_func()->pendingChildInsertedEvents.isEmpty()) {
- QCoreApplication::postEvent(parent,
- new QEvent(QEvent::ChildInsertedRequest),
- Qt::HighEventPriority);
+ if (QCoreApplicationPrivate::useQt3Support) {
+ if (parent->d_func()->pendingChildInsertedEvents.isEmpty()) {
+ QCoreApplication::postEvent(parent,
+ new QEvent(QEvent::ChildInsertedRequest),
+ Qt::HighEventPriority);
+ }
+ parent->d_func()->pendingChildInsertedEvents.append(q);
}
- parent->d_func()->pendingChildInsertedEvents.append(q);
#endif
}
}
@@ -2305,7 +2287,7 @@ static void err_info_about_objects(const char * func,
a thread different from this object's thread. Do not use this
function in this type of scenario.
- \sa QSignalMapper
+ \sa senderSignalIndex(), QSignalMapper
*/
QObject *QObject::sender() const
@@ -2316,13 +2298,53 @@ QObject *QObject::sender() const
if (!d->currentSender)
return 0;
- // Return 0 if d->currentSender isn't in d->senders
- bool found = false;
- for (QObjectPrivate::Connection *c = d->senders; c && !found; c = c->next)
- found = (c->sender == d->currentSender->sender);
- if (!found)
- return 0;
- return d->currentSender->sender;
+ for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
+ if (c->sender == d->currentSender->sender)
+ return d->currentSender->sender;
+ }
+
+ return 0;
+}
+
+/*!
+ \since 4.8
+
+ Returns the meta-method index of the signal that called the currently
+ executing slot, which is a member of the class returned by sender().
+ If called outside of a slot activated by a signal, -1 is returned.
+
+ For signals with default parameters, this function will always return
+ the index with all parameters, regardless of which was used with
+ connect(). For example, the signal \c {destroyed(QObject *obj = 0)}
+ will have two different indexes (with and without the parameter), but
+ this function will always return the index with a parameter. This does
+ not apply when overloading signals with different parameters.
+
+ \warning This function violates the object-oriented principle of
+ modularity. However, getting access to the signal index might be useful
+ when many signals are connected to a single slot.
+
+ \warning The return value of this function is not valid when the slot
+ is called via a Qt::DirectConnection from a thread different from this
+ object's thread. Do not use this function in this type of scenario.
+
+ \sa sender(), QMetaObject::indexOfSignal(), QMetaObject::method()
+*/
+
+int QObject::senderSignalIndex() const
+{
+ Q_D(const QObject);
+
+ QMutexLocker locker(signalSlotLock(this));
+ if (!d->currentSender)
+ return -1;
+
+ for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
+ if (c->sender == d->currentSender->sender)
+ return d->currentSender->signal;
+ }
+
+ return -1;
}
/*!
@@ -2384,6 +2406,71 @@ int QObject::receivers(const char *signal) const
}
/*!
+ \internal
+
+ This helper function calculates signal and method index for the given
+ member in the specified class.
+
+ \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
+
+ \li If specified member is not a member of obj instance class (or one of
+ its parent classes) then both signalIndex and methodIndex are set to -1.
+
+ This function is used by QObject::connect and QObject::disconnect which
+ are working with QMetaMethod.
+
+ \param[out] signalIndex is set to the signal index of member. If the member
+ specified is not signal this variable is set to -1.
+
+ \param[out] methodIndex is set to the method index of the member. If the
+ member is not a method of the object specified by obj param this variable
+ is set to -1.
+*/
+void QMetaObjectPrivate::memberIndexes(const QObject *obj,
+ const QMetaMethod &member,
+ int *signalIndex, int *methodIndex)
+{
+ *signalIndex = -1;
+ *methodIndex = -1;
+ if (!obj || !member.mobj)
+ return;
+ const QMetaObject *m = obj->metaObject();
+ // Check that member is member of obj class
+ while (m != 0 && m != member.mobj)
+ m = m->d.superdata;
+ if (!m)
+ return;
+ *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
+
+ int signalOffset;
+ int methodOffset;
+ computeOffsets(m, &signalOffset, &methodOffset);
+
+ *methodIndex += methodOffset;
+ if (member.methodType() == QMetaMethod::Signal) {
+ *signalIndex = originalClone(m, *signalIndex);
+ *signalIndex += signalOffset;
+ } else {
+ *signalIndex = -1;
+ }
+}
+
+static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
+ const QMetaObject *receiver, const QMetaMethod &method)
+{
+ if (signal.attributes() & QMetaMethod::Compatibility) {
+ if (!(method.attributes() & QMetaMethod::Compatibility))
+ qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
+ sender->className(), signal.signature());
+ } else if ((method.attributes() & QMetaMethod::Compatibility) &&
+ method.methodType() == QMetaMethod::Signal) {
+ qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
+ sender->className(), signal.signature(),
+ receiver->className(), method.signature());
+ }
+}
+
+/*!
\threadsafe
Creates a connection of the given \a type from the \a signal in
@@ -2560,7 +2647,7 @@ bool QObject::connect(const QObject *sender, const char *signal,
}
int *types = 0;
- if ((type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
+ if ((type == Qt::QueuedConnection)
&& !(types = queuedConnectionTypes(smeta->method(signal_absolute_index).parameterTypes())))
return false;
@@ -2568,15 +2655,8 @@ bool QObject::connect(const QObject *sender, const char *signal,
{
QMetaMethod smethod = smeta->method(signal_absolute_index);
QMetaMethod rmethod = rmeta->method(method_index);
- if (warnCompat) {
- if(smethod.attributes() & QMetaMethod::Compatibility) {
- if (!(rmethod.attributes() & QMetaMethod::Compatibility))
- qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)", smeta->className(), signal);
- } else if(rmethod.attributes() & QMetaMethod::Compatibility && membcode != QSIGNAL_CODE) {
- qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
- smeta->className(), signal, rmeta->className(), method);
- }
- }
+ if (warnCompat)
+ check_and_warn_compat(smeta, smethod, rmeta, rmethod);
}
#endif
if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, type, types))
@@ -2585,6 +2665,111 @@ bool QObject::connect(const QObject *sender, const char *signal,
return true;
}
+/*!
+ \since 4.8
+
+ Creates a connection of the given \a type from the \a signal in
+ the \a sender object to the \a method in the \a receiver object.
+ Returns true if the connection succeeds; otherwise returns false.
+
+ This function works in the same way as
+ connect(const QObject *sender, const char *signal,
+ const QObject *receiver, const char *method,
+ Qt::ConnectionType type)
+ but it uses QMetaMethod to specify signal and method.
+
+ \see connect(const QObject *sender, const char *signal,
+ const QObject *receiver, const char *method,
+ Qt::ConnectionType type)
+ */
+bool QObject::connect(const QObject *sender, const QMetaMethod &signal,
+ const QObject *receiver, const QMetaMethod &method,
+ Qt::ConnectionType type)
+{
+#ifndef QT_NO_DEBUG
+ bool warnCompat = true;
+#endif
+ if (type == Qt::AutoCompatConnection) {
+ type = Qt::AutoConnection;
+#ifndef QT_NO_DEBUG
+ warnCompat = false;
+#endif
+ }
+
+ if (sender == 0
+ || receiver == 0
+ || signal.methodType() != QMetaMethod::Signal
+ || method.methodType() == QMetaMethod::Constructor) {
+ qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
+ sender ? sender->metaObject()->className() : "(null)",
+ signal.signature(),
+ receiver ? receiver->metaObject()->className() : "(null)",
+ method.signature() );
+ return false;
+ }
+
+ // Reconstructing SIGNAL() macro result for signal.signature() string
+ QByteArray signalSignature;
+ signalSignature.reserve(qstrlen(signal.signature())+1);
+ signalSignature.append((char)(QSIGNAL_CODE + '0'));
+ signalSignature.append(signal.signature());
+
+ {
+ QByteArray methodSignature;
+ methodSignature.reserve(qstrlen(method.signature())+1);
+ methodSignature.append((char)(method.methodType() == QMetaMethod::Slot ? QSLOT_CODE
+ : method.methodType() == QMetaMethod::Signal ? QSIGNAL_CODE : 0 + '0'));
+ methodSignature.append(method.signature());
+ const void *cbdata[] = { sender, signalSignature.constData(), receiver, methodSignature.constData(), &type };
+ if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
+ return true;
+ }
+
+
+ int signal_index;
+ int method_index;
+ {
+ int dummy;
+ QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
+ QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
+ }
+
+ const QMetaObject *smeta = sender->metaObject();
+ const QMetaObject *rmeta = receiver->metaObject();
+ if (signal_index == -1) {
+ qWarning("QObject::connect: Can't find signal %s on instance of class %s",
+ signal.signature(), smeta->className());
+ return false;
+ }
+ if (method_index == -1) {
+ qWarning("QObject::connect: Can't find method %s on instance of class %s",
+ method.signature(), rmeta->className());
+ return false;
+ }
+
+ if (!QMetaObject::checkConnectArgs(signal.signature(), method.signature())) {
+ qWarning("QObject::connect: Incompatible sender/receiver arguments"
+ "\n %s::%s --> %s::%s",
+ smeta->className(), signal.signature(),
+ rmeta->className(), method.signature());
+ return false;
+ }
+
+ int *types = 0;
+ if ((type == Qt::QueuedConnection)
+ && !(types = queuedConnectionTypes(signal.parameterTypes())))
+ return false;
+
+#ifndef QT_NO_DEBUG
+ if (warnCompat)
+ check_and_warn_compat(smeta, signal, rmeta, method);
+#endif
+ if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, type, types))
+ return false;
+
+ const_cast<QObject*>(sender)->connectNotify(signalSignature.constData());
+ return true;
+}
/*!
\fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
@@ -2764,6 +2949,107 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
return res;
}
+/*!
+ \since 4.8
+
+ Disconnects \a signal in object \a sender from \a method in object
+ \a receiver. Returns true if the connection is successfully broken;
+ otherwise returns false.
+
+ This function provides the same posibilities like
+ disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
+ but uses QMetaMethod to represent the signal and the method to be disconnected.
+
+ Additionally this function returnsfalse and no signals and slots disconnected
+ if:
+ \list 1
+
+ \i \a signal is not a member of sender class or one of its parent classes.
+
+ \i \a method is not a member of receiver class or one of its parent classes.
+
+ \i \a signal instance represents not a signal.
+
+ \endlist
+
+ QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
+ In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
+ method shoud also be QMetaMethod(). \a sender parameter should be never 0.
+
+ \see disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
+ */
+bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
+ const QObject *receiver, const QMetaMethod &method)
+{
+ if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
+ qWarning("Object::disconnect: Unexpected null parameter");
+ return false;
+ }
+ if (signal.mobj) {
+ if(signal.methodType() != QMetaMethod::Signal) {
+ qWarning("Object::%s: Attempt to %s non-signal %s::%s",
+ "disconnect","unbind",
+ sender->metaObject()->className(), signal.signature());
+ return false;
+ }
+ }
+ if (method.mobj) {
+ if(method.methodType() == QMetaMethod::Constructor) {
+ qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
+ receiver->metaObject()->className(), method.signature());
+ return false;
+ }
+ }
+
+ // Reconstructing SIGNAL() macro result for signal.signature() string
+ QByteArray signalSignature;
+ if (signal.mobj) {
+ signalSignature.reserve(qstrlen(signal.signature())+1);
+ signalSignature.append((char)(QSIGNAL_CODE + '0'));
+ signalSignature.append(signal.signature());
+ }
+
+ {
+ QByteArray methodSignature;
+ if (method.mobj) {
+ methodSignature.reserve(qstrlen(method.signature())+1);
+ methodSignature.append((char)(method.methodType() == QMetaMethod::Slot ? QSLOT_CODE
+ : method.methodType() == QMetaMethod::Signal ? QSIGNAL_CODE : 0 + '0'));
+ methodSignature.append(method.signature());
+ }
+ const void *cbdata[] = { sender, signal.mobj ? signalSignature.constData() : 0,
+ receiver, method.mobj ? methodSignature.constData() : 0 };
+ if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
+ return true;
+ }
+
+ int signal_index;
+ int method_index;
+ {
+ int dummy;
+ QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
+ QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
+ }
+ // If we are here sender is not null. If signal is not null while signal_index
+ // is -1 then this signal is not a member of sender.
+ if (signal.mobj && signal_index == -1) {
+ qWarning("QObject::disconect: signal %s not found on class %s",
+ signal.signature(), sender->metaObject()->className());
+ return false;
+ }
+ // If this condition is true then method is not a member of receeiver.
+ if (receiver && method.mobj && method_index == -1) {
+ qWarning("QObject::disconect: method %s not found on class %s",
+ method.signature(), receiver->metaObject()->className());
+ return false;
+ }
+
+ if (!QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index))
+ return false;
+
+ const_cast<QObject*>(sender)->disconnectNotify(method.mobj ? signalSignature.constData() : 0);
+ return true;
+}
/*!
\threadsafe
@@ -2981,7 +3267,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
}
if (needToUnlock)
- receiverMutex->unlock();
+ receiverMutex->unlockInline();
c->receiver = 0;
@@ -3068,7 +3354,7 @@ void QMetaObject::connectSlotsByName(QObject *o)
return;
const QMetaObject *mo = o->metaObject();
Q_ASSERT(mo);
- const QObjectList list = qFindChildren<QObject *>(o, QString());
+ const QObjectList list = o->findChildren<QObject *>(QString());
for (int i = 0; i < mo->methodCount(); ++i) {
const char *slot = mo->method(i).signature();
Q_ASSERT(slot);
@@ -3115,8 +3401,7 @@ void QMetaObject::connectSlotsByName(QObject *o)
}
}
-static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c,
- void **argv, QSemaphore *semaphore = 0)
+static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
{
if (!c->argumentTypes && c->argumentTypes != &DIRECT_CONNECTION_ONLY) {
QMetaMethod m = sender->metaObject()->method(signal);
@@ -3146,30 +3431,9 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
signal,
nargs,
types,
- args,
- semaphore));
+ args));
}
-static void blocking_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
-{
- if (QThread::currentThread() == c->receiver->thread()) {
- qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
- "Sender is %s(%p), receiver is %s(%p)",
- sender->metaObject()->className(), sender,
- c->receiver->metaObject()->className(), c->receiver);
- }
-
-#ifdef QT_NO_THREAD
- queued_activate(sender, signal, c, argv);
-#else
- QSemaphore semaphore;
- queued_activate(sender, signal, c, argv, &semaphore);
- QMutex *mutex = signalSlotLock(sender);
- mutex->unlock();
- semaphore.acquire();
- mutex->lock();
-#endif
-}
/*!\internal
\obsolete.
@@ -3233,23 +3497,38 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
continue;
QObject * const receiver = c->receiver;
+ const int method = c->method;
+ const bool receiverInSameThread = currentThreadData == receiver->d_func()->threadData;
// determine if this connection should be sent immediately or
// put into the event queue
if ((c->connectionType == Qt::AutoConnection
- && (currentThreadData != sender->d_func()->threadData
+ && (!receiverInSameThread
|| receiver->d_func()->threadData != sender->d_func()->threadData))
|| (c->connectionType == Qt::QueuedConnection)) {
queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
continue;
+#ifndef QT_NO_THREAD
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
- blocking_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
+ locker.unlock();
+ if (receiverInSameThread) {
+ qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
+ "Sender is %s(%p), receiver is %s(%p)",
+ sender->metaObject()->className(), sender,
+ receiver->metaObject()->className(), receiver);
+ }
+ QSemaphore semaphore;
+ QCoreApplication::postEvent(receiver, new QMetaCallEvent(method,
+ sender, signal_absolute_index,
+ 0, 0,
+ argv ? argv : empty_argv,
+ &semaphore));
+ semaphore.acquire();
+ locker.relock();
continue;
+#endif
}
-
- const int method = c->method;
QObjectPrivate::Sender currentSender;
- const bool receiverInSameThread = currentThreadData == receiver->d_func()->threadData;
QObjectPrivate::Sender *previousSender = 0;
if (receiverInSameThread) {
currentSender.sender = sender;
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index d98d1f0d6f..63fdf76801 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -77,19 +77,9 @@ class QObjectUserData;
typedef QList<QObject*> QObjectList;
-#if defined Q_CC_MSVC && _MSC_VER < 1300
-template<typename T> inline T qFindChild(const QObject *o, const QString &name = QString(), T = 0);
-template<typename T> inline QList<T> qFindChildren(const QObject *o, const QString &name = QString(), T = 0);
-# ifndef QT_NO_REGEXP
-template<typename T> inline QList<T> qFindChildren(const QObject *o, const QRegExp &re, T = 0);
-# endif
-#else
-template<typename T> inline T qFindChild(const QObject *, const QString & = QString());
-template<typename T> inline QList<T> qFindChildren(const QObject *, const QString & = QString());
-# ifndef QT_NO_REGEXP
-template<typename T> inline QList<T> qFindChildren(const QObject *, const QRegExp &);
-# endif
-#endif
+Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
+ const QMetaObject &mo, QList<void *> *list);
+Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo);
class
#if defined(__INTEL_COMPILER) && defined(Q_OS_WIN)
@@ -109,7 +99,7 @@ public:
uint ownObjectName : 1;
uint sendChildEvents : 1;
uint receiveChildEvents : 1;
- uint inEventHandler : 1;
+ uint inEventHandler : 1; //only used if QT_JAMBI_BUILD
uint inThreadChangeEvent : 1;
uint hasGuards : 1; //true iff there is one or more QPointer attached to this object
uint unused : 22;
@@ -164,20 +154,36 @@ public:
int startTimer(int interval);
void killTimer(int id);
-#ifndef QT_NO_MEMBER_TEMPLATES
template<typename T>
inline T findChild(const QString &aName = QString()) const
- { return qFindChild<T>(this, aName); }
+ { return static_cast<T>(qt_qFindChild_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject)); }
template<typename T>
inline QList<T> findChildren(const QString &aName = QString()) const
- { return qFindChildren<T>(this, aName); }
+ {
+ QList<T> list;
+ union {
+ QList<T> *typedList;
+ QList<void *> *voidList;
+ } u;
+ u.typedList = &list;
+ qt_qFindChildren_helper(this, aName, 0, reinterpret_cast<T>(0)->staticMetaObject, u.voidList);
+ return list;
+ }
#ifndef QT_NO_REGEXP
template<typename T>
inline QList<T> findChildren(const QRegExp &re) const
- { return qFindChildren<T>(this, re); }
-#endif
+ {
+ QList<T> list;
+ union {
+ QList<T> *typedList;
+ QList<void *> *voidList;
+ } u;
+ u.typedList = &list;
+ qt_qFindChildren_helper(this, QString(), &re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList);
+ return list;
+ }
#endif
#ifdef QT3_SUPPORT
@@ -207,6 +213,21 @@ public:
#endif
#endif
);
+
+ static bool connect(const QObject *sender, const QMetaMethod &signal,
+ const QObject *receiver, const QMetaMethod &method,
+ Qt::ConnectionType type =
+#ifdef qdoc
+ Qt::AutoConnection
+#else
+#ifdef QT3_SUPPORT
+ Qt::AutoCompatConnection
+#else
+ Qt::AutoConnection
+#endif
+#endif
+ );
+
inline bool connect(const QObject *sender, const char *signal,
const char *member, Qt::ConnectionType type =
#ifdef qdoc
@@ -222,6 +243,8 @@ public:
static bool disconnect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member);
+ static bool disconnect(const QObject *sender, const QMetaMethod &signal,
+ const QObject *receiver, const QMetaMethod &member);
inline bool disconnect(const char *signal = 0,
const QObject *receiver = 0, const char *member = 0)
{ return disconnect(this, signal, receiver, member); }
@@ -257,6 +280,7 @@ public Q_SLOTS:
protected:
QObject *sender() const;
+ int senderSignalIndex() const;
int receivers(const char* signal) const;
virtual void timerEvent(QTimerEvent *);
@@ -321,46 +345,31 @@ public:
};
#endif
-Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
- const QMetaObject &mo, QList<void *> *list);
-Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo);
-
+#ifdef QT_DEPRECATED
template<typename T>
-inline T qFindChild(const QObject *o, const QString &name)
-{ return static_cast<T>(qt_qFindChild_helper(o, name, reinterpret_cast<T>(0)->staticMetaObject)); }
+inline QT_DEPRECATED T qFindChild(const QObject *o, const QString &name = QString())
+{ return o->findChild<T>(name); }
template<typename T>
-inline QList<T> qFindChildren(const QObject *o, const QString &name)
+inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QString &name = QString())
{
- QList<T> list;
- union {
- QList<T> *typedList;
- QList<void *> *voidList;
- } u;
- u.typedList = &list;
- qt_qFindChildren_helper(o, name, 0, reinterpret_cast<T>(0)->staticMetaObject, u.voidList);
- return list;
+ return o->findChildren<T>(name);
}
#ifndef QT_NO_REGEXP
template<typename T>
-inline QList<T> qFindChildren(const QObject *o, const QRegExp &re)
+inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QRegExp &re)
{
- QList<T> list;
- union {
- QList<T> *typedList;
- QList<void *> *voidList;
- } u;
- u.typedList = &list;
- qt_qFindChildren_helper(o, QString(), &re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList);
- return list;
+ return o->findChildren<T>(re);
}
#endif
+#endif //QT_DEPRECATED
+
template <class T>
inline T qobject_cast(QObject *object)
{
-#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(QT_NO_QOBJECT_CHECK)
+#if !defined(QT_NO_QOBJECT_CHECK)
reinterpret_cast<T>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(object));
#endif
return static_cast<T>(reinterpret_cast<T>(0)->staticMetaObject.cast(object));
@@ -369,14 +378,10 @@ inline T qobject_cast(QObject *object)
template <class T>
inline T qobject_cast(const QObject *object)
{
- // this will cause a compilation error if T is not const
- register T ptr = static_cast<T>(object);
- Q_UNUSED(ptr);
-
-#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(QT_NO_QOBJECT_CHECK)
+#if !defined(QT_NO_QOBJECT_CHECK)
reinterpret_cast<T>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
#endif
- return static_cast<T>(const_cast<QObject *>(reinterpret_cast<T>(0)->staticMetaObject.cast(const_cast<QObject *>(object))));
+ return static_cast<T>(reinterpret_cast<T>(0)->staticMetaObject.cast(object));
}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 4800e6a020..82023d4001 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -55,6 +55,7 @@
#include "QtCore/qobject.h"
#include "QtCore/qpointer.h"
+#include "QtCore/qsharedpointer.h"
#include "QtCore/qcoreevent.h"
#include "QtCore/qlist.h"
#include "QtCore/qvector.h"
@@ -153,7 +154,6 @@ public:
#ifdef QT3_SUPPORT
void sendPendingChildInsertedEvents();
- void removePendingChildInsertedEvents(QObject *child);
#endif
static inline Sender *setCurrentSender(QObject *receiver,
@@ -161,8 +161,10 @@ public:
static inline void resetCurrentSender(QObject *receiver,
Sender *currentSender,
Sender *previousSender);
+#ifdef QT_JAMBI_BUILD
static int *setDeleteWatch(QObjectPrivate *d, int *newWatch);
static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch);
+#endif
static void clearGuards(QObject *);
static QObjectPrivate *get(QObject *o) {
@@ -184,7 +186,7 @@ public:
mutable quint32 connectedSignals[2];
#ifdef QT3_SUPPORT
- QList<QObject *> pendingChildInsertedEvents;
+ QVector< QWeakPointer<QObject> > pendingChildInsertedEvents;
#else
// preserve binary compatibility with code compiled without Qt 3 support
// keeping the binary layout stable helps the Qt Creator debugger
@@ -200,7 +202,9 @@ public:
// these objects are all used to indicate that a QObject was deleted
// plus QPointer, which keeps a separate list
QAtomicPointer<QtSharedPointer::ExternalRefCountData> sharedRefcount;
+#ifdef QT_JAMBI_BUILD
int *deleteWatch;
+#endif
};
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 555a1f5c40..db46ba5c9c 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -117,7 +117,7 @@ class QString;
# define QT_TR_FUNCTIONS
#endif
-#if defined(QT_NO_MEMBER_TEMPLATES) || defined(QT_NO_QOBJECT_CHECK)
+#if defined(QT_NO_QOBJECT_CHECK)
/* tmake ignore Q_OBJECT */
#define Q_OBJECT_CHECK
#else
@@ -144,7 +144,7 @@ inline int qYouForgotTheQ_OBJECT_Macro(T, T) { return 0; }
template <typename T1, typename T2>
inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {}
-#endif // QT_NO_MEMBER_TEMPLATES
+#endif // QT_NO_QOBJECT_CHECK
#ifdef Q_NO_DATA_RELOCATION
#define Q_OBJECT_GETSTATICMETAOBJECT static const QMetaObject &getStaticMetaObject();
@@ -298,6 +298,7 @@ struct Q_CORE_EXPORT QMetaObject
const QMetaObject *superClass() const;
QObject *cast(QObject *obj) const;
+ const QObject *cast(const QObject *obj) const;
#ifndef QT_NO_TRANSLATION
// ### Qt 4: Merge overloads
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index fe93ebc330..0782ffe305 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -142,9 +142,12 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
remain. Do not mix using QtSharedMemory and QSharedMemory. Port
everything to QSharedMemory.
- \warning QSharedMemory changes the key in a Qt-specific way.
- It is therefore currently not possible to use the shared memory of
- non-Qt applications with QSharedMemory.
+ \warning QSharedMemory changes the key in a Qt-specific way, unless otherwise
+ specified. Interoperation with non-Qt applications is achieved by first creating
+ a default shared memory with QSharedMemory() and then setting a native key with
+ setNativeKey(). When using native keys, shared memory is not protected against
+ multiple accesses on it (e.g. unable to lock()) and a user-defined mechanism
+ should be used to achieve a such protection.
*/
/*!
@@ -153,8 +156,8 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
Constructs a shared memory object with the given \a parent. The
shared memory object's key is not set by the constructor, so the
shared memory object does not have an underlying shared memory
- segment attached. The key must be set with setKey() before create()
- or attach() can be used.
+ segment attached. The key must be set with setKey() or setNativeKey()
+ before create() or attach() can be used.
\sa setKey()
*/
@@ -191,24 +194,62 @@ QSharedMemory::~QSharedMemory()
}
/*!
- Sets a new \a key for this shared memory object. If \a key and the
- current key are the same, the function returns without doing
- anything. If the shared memory object is attached to an underlying
- shared memory segment, it will \l {detach()} {detach} from it before
- setting the new key. This function does not do an attach().
+ Sets the platform independent \a key for this shared memory object. If \a key
+ is the same as the current key, the function returns without doing anything.
- \sa key() isAttached()
- */
+ You can call key() to retrieve the platform independent key. Internally,
+ QSharedMemory converts this key into a platform specific key. If you instead
+ call nativeKey(), you will get the platform specific, converted key.
+
+ If the shared memory object is attached to an underlying shared memory
+ segment, it will \l {detach()} {detach} from it before setting the new key.
+ This function does not do an attach().
+
+ \sa key() nativeKey() isAttached()
+*/
void QSharedMemory::setKey(const QString &key)
{
Q_D(QSharedMemory);
- if (key == d->key)
+ if (key == d->key && d->makePlatformSafeKey(key) == d->nativeKey)
return;
if (isAttached())
detach();
d->cleanHandle();
d->key = key;
+ d->nativeKey = d->makePlatformSafeKey(key);
+}
+
+/*!
+ \since 4.8
+
+ Sets the native, platform specific, \a key for this shared memory object. If
+ \a key is the same as the current native key, the function returns without
+ doing anything. If all you want is to assign a key to a segment, you should
+ call setKey() instead.
+
+ You can call nativeKey() to retrieve the native key. If a native key has been
+ assigned, calling key() will return a null string.
+
+ If the shared memory object is attached to an underlying shared memory
+ segment, it will \l {detach()} {detach} from it before setting the new key.
+ This function does not do an attach().
+
+ The application will not be portable if you set a native key.
+
+ \sa nativeKey() key() isAttached()
+*/
+void QSharedMemory::setNativeKey(const QString &key)
+{
+ Q_D(QSharedMemory);
+ if (key == d->nativeKey && d->key.isNull())
+ return;
+
+ if (isAttached())
+ detach();
+ d->cleanHandle();
+ d->key = QString();
+ d->nativeKey = key;
}
bool QSharedMemoryPrivate::initKey()
@@ -251,13 +292,15 @@ bool QSharedMemoryPrivate::initKey()
}
/*!
- Returns the key assigned to this shared memory. The key is the
- identifier used by the operating system to identify the shared
- memory segment. When QSharedMemory is used for interprocess
- communication, the key is how each process attaches to the shared
- memory segment through which the IPC occurs.
+ Returns the key assigned with setKey() to this shared memory, or a null key
+ if no key has been assigned, or if the segment is using a nativeKey(). The
+ key is the identifier used by Qt applications to identify the shared memory
+ segment.
+
+ You can find the native, platform specific, key used by the operating system
+ by calling nativeKey().
- \sa setKey()
+ \sa setKey() setNativeKey()
*/
QString QSharedMemory::key() const
{
@@ -266,13 +309,30 @@ QString QSharedMemory::key() const
}
/*!
- Creates a shared memory segment of \a size bytes with the key passed
- to the constructor or set with setKey(), attaches to the new shared
- memory segment with the given access \a mode, and returns \tt true.
- If a shared memory segment identified by the key already exists, the
- attach operation is not performed, and \tt false is returned. When
- the return value is \tt false, call error() to determine which error
- occurred.
+ \since 4.8
+
+ Returns the native, platform specific, key for this shared memory object. The
+ native key is the identifier used by the operating system to identify the
+ shared memory segment.
+
+ You can use the native key to access shared memory segments that have not
+ been created by Qt, or to grant shared memory access to non-Qt applications.
+
+ \sa setKey() setNativeKey()
+*/
+QString QSharedMemory::nativeKey() const
+{
+ Q_D(const QSharedMemory);
+ return d->nativeKey;
+}
+
+/*!
+ Creates a shared memory segment of \a size bytes with the key passed to the
+ constructor, set with setKey() or set with setNativeKey(), then attaches to
+ the new shared memory segment with the given access \a mode and returns
+ \tt true. If a shared memory segment identified by the key already exists,
+ the attach operation is not performed and \tt false is returned. When the
+ return value is \tt false, call error() to determine which error occurred.
\sa error()
*/
@@ -294,7 +354,7 @@ bool QSharedMemory::create(int size, AccessMode mode)
QString function = QLatin1String("QSharedMemory::create");
#ifndef QT_NO_SYSTEMSEMAPHORE
QSharedMemoryLocker lock(this);
- if (!d->tryLocker(&lock, function))
+ if (!d->key.isNull() && !d->tryLocker(&lock, function))
return false;
#endif
@@ -338,7 +398,7 @@ int QSharedMemory::size() const
/*!
Attempts to attach the process to the shared memory segment
identified by the key that was passed to the constructor or to a
- call to setKey(). The access \a mode is \l {QSharedMemory::}
+ call to setKey() or setNativeKey(). The access \a mode is \l {QSharedMemory::}
{ReadWrite} by default. It can also be \l {QSharedMemory::}
{ReadOnly}. Returns true if the attach operation is successful. If
false is returned, call error() to determine which error occurred.
@@ -355,7 +415,7 @@ bool QSharedMemory::attach(AccessMode mode)
return false;
#ifndef QT_NO_SYSTEMSEMAPHORE
QSharedMemoryLocker lock(this);
- if (!d->tryLocker(&lock, QLatin1String("QSharedMemory::attach")))
+ if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::attach")))
return false;
#endif
@@ -395,7 +455,7 @@ bool QSharedMemory::detach()
#ifndef QT_NO_SYSTEMSEMAPHORE
QSharedMemoryLocker lock(this);
- if (!d->tryLocker(&lock, QLatin1String("QSharedMemory::detach")))
+ if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::detach")))
return false;
#endif
@@ -451,9 +511,9 @@ const void *QSharedMemory::data() const
by this process and returns true. If another process has locked the
segment, this function blocks until the lock is released. Then it
acquires the lock and returns true. If this function returns false,
- it means either that you have ignored a false return from create()
- or attach(), or that QSystemSemaphore::acquire() failed due to an
- unknown system error.
+ it means that you have ignored a false return from create() or attach(),
+ that you have set the key with setNativeKey() or that
+ QSystemSemaphore::acquire() failed due to an unknown system error.
\sa unlock(), data(), QSystemSemaphore::acquire()
*/
diff --git a/src/corelib/kernel/qsharedmemory.h b/src/corelib/kernel/qsharedmemory.h
index fba939cbac..5673f43cee 100644
--- a/src/corelib/kernel/qsharedmemory.h
+++ b/src/corelib/kernel/qsharedmemory.h
@@ -85,6 +85,8 @@ public:
void setKey(const QString &key);
QString key() const;
+ void setNativeKey(const QString &key);
+ QString nativeKey() const;
bool create(int size, AccessMode mode = ReadWrite);
int size() const;
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index a52f8b3f08..632a6e928c 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -122,6 +122,7 @@ public:
void *memory;
int size;
QString key;
+ QString nativeKey;
QSharedMemory::SharedMemoryError error;
QString errorString;
#ifndef QT_NO_SYSTEMSEMAPHORE
diff --git a/src/corelib/kernel/qsharedmemory_symbian.cpp b/src/corelib/kernel/qsharedmemory_symbian.cpp
index 9b84eb5658..091c2b5177 100644
--- a/src/corelib/kernel/qsharedmemory_symbian.cpp
+++ b/src/corelib/kernel/qsharedmemory_symbian.cpp
@@ -107,16 +107,14 @@ bool QSharedMemoryPrivate::cleanHandle()
bool QSharedMemoryPrivate::create(int size)
{
- // Get a windows acceptable key
- QString safeKey = makePlatformSafeKey(key);
QString function = QLatin1String("QSharedMemory::create");
- if (safeKey.isEmpty()) {
+ if (nativeKey.isEmpty()) {
error = QSharedMemory::KeyError;
errorString = QSharedMemory::tr("%1: key error").arg(function);
return false;
}
- TPtrC ptr(qt_QString2TPtrC(safeKey));
+ TPtrC ptr(qt_QString2TPtrC(nativeKey));
TInt err = chunk.CreateGlobal(ptr, size, size);
@@ -136,14 +134,13 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode /* mode */)
// Grab a pointer to the memory block
if (!chunk.Handle()) {
QString function = QLatin1String("QSharedMemory::handle");
- QString safeKey = makePlatformSafeKey(key);
- if (safeKey.isEmpty()) {
+ if (nativeKey.isEmpty()) {
error = QSharedMemory::KeyError;
errorString = QSharedMemory::tr("%1: unable to make key").arg(function);
return false;
}
- TPtrC ptr(qt_QString2TPtrC(safeKey));
+ TPtrC ptr(qt_QString2TPtrC(nativeKey));
TInt err = KErrNoMemory;
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index a5f79c25d6..064979b0f6 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -116,21 +116,20 @@ key_t QSharedMemoryPrivate::handle()
return unix_key;
// don't allow making handles on empty keys
- if (key.isEmpty()) {
+ if (nativeKey.isEmpty()) {
errorString = QSharedMemory::tr("%1: key is empty").arg(QLatin1String("QSharedMemory::handle:"));
error = QSharedMemory::KeyError;
return 0;
}
// ftok requires that an actual file exists somewhere
- QString fileName = makePlatformSafeKey(key);
- if (!QFile::exists(fileName)) {
+ if (!QFile::exists(nativeKey)) {
errorString = QSharedMemory::tr("%1: UNIX key file doesn't exist").arg(QLatin1String("QSharedMemory::handle:"));
error = QSharedMemory::NotFound;
return 0;
}
- unix_key = ftok(QFile::encodeName(fileName).constData(), 'Q');
+ unix_key = ftok(QFile::encodeName(nativeKey).constData(), 'Q');
if (-1 == unix_key) {
errorString = QSharedMemory::tr("%1: ftok failed").arg(QLatin1String("QSharedMemory::handle:"));
error = QSharedMemory::KeyError;
@@ -181,7 +180,7 @@ bool QSharedMemoryPrivate::create(int size)
{
// build file if needed
bool createdFile = false;
- int built = createUnixKeyFile(makePlatformSafeKey(key));
+ int built = createUnixKeyFile(nativeKey);
if (built == -1) {
errorString = QSharedMemory::tr("%1: unable to make key").arg(QLatin1String("QSharedMemory::handle:"));
error = QSharedMemory::KeyError;
@@ -194,7 +193,7 @@ bool QSharedMemoryPrivate::create(int size)
// get handle
if (!handle()) {
if (createdFile)
- QFile::remove(makePlatformSafeKey(key));
+ QFile::remove(nativeKey);
return false;
}
@@ -210,7 +209,7 @@ bool QSharedMemoryPrivate::create(int size)
setErrorString(function);
}
if (createdFile && error != QSharedMemory::AlreadyExists)
- QFile::remove(makePlatformSafeKey(key));
+ QFile::remove(nativeKey);
return false;
}
@@ -295,7 +294,7 @@ bool QSharedMemoryPrivate::detach()
}
// remove file
- if (!QFile::remove(makePlatformSafeKey(key)))
+ if (!QFile::remove(nativeKey))
return false;
}
return true;
diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp
index 0f5fdc7f86..0cdb123703 100644
--- a/src/corelib/kernel/qsharedmemory_win.cpp
+++ b/src/corelib/kernel/qsharedmemory_win.cpp
@@ -99,18 +99,17 @@ HANDLE QSharedMemoryPrivate::handle()
{
if (!hand) {
QString function = QLatin1String("QSharedMemory::handle");
- QString safeKey = makePlatformSafeKey(key);
- if (safeKey.isEmpty()) {
+ if (nativeKey.isEmpty()) {
error = QSharedMemory::KeyError;
errorString = QSharedMemory::tr("%1: unable to make key").arg(function);
return false;
}
#ifndef Q_OS_WINCE
- hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, (wchar_t*)safeKey.utf16());
+ hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, (wchar_t*)nativeKey.utf16());
#else
// This works for opening a mapping too, but always opens it with read/write access in
// attach as it seems.
- hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 0, (wchar_t*)safeKey.utf16());
+ hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 0, (wchar_t*)nativeKey.utf16());
#endif
if (!hand) {
setErrorString(function);
@@ -133,17 +132,15 @@ bool QSharedMemoryPrivate::cleanHandle()
bool QSharedMemoryPrivate::create(int size)
{
- // Get a windows acceptable key
- QString safeKey = makePlatformSafeKey(key);
QString function = QLatin1String("QSharedMemory::create");
- if (safeKey.isEmpty()) {
+ if (nativeKey.isEmpty()) {
error = QSharedMemory::KeyError;
errorString = QSharedMemory::tr("%1: key error").arg(function);
return false;
}
// Create the file mapping.
- hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, (wchar_t*)safeKey.utf16());
+ hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, (wchar_t*)nativeKey.utf16());
setErrorString(function);
// hand is valid when it already exists unlike unix so explicitly check
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index f5d7c0def1..feb85ce714 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -947,11 +947,7 @@ static bool convert(const QVariant::Private *d, QVariant::Type t, void *result,
case QMetaType::UChar:
case QMetaType::UShort:
case QMetaType::ULong:
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- *f = (double)(qlonglong)qMetaTypeUNumber(d);
-#else
*f = double(qMetaTypeUNumber(d));
-#endif
break;
default:
*f = 0.0;
@@ -986,11 +982,7 @@ static bool convert(const QVariant::Private *d, QVariant::Type t, void *result,
case QMetaType::UChar:
case QMetaType::UShort:
case QMetaType::ULong:
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- *f = (float)(qlonglong)qMetaTypeUNumber(d);
-#else
*f = float(qMetaTypeUNumber(d));
-#endif
break;
default:
*f = 0.0f;
@@ -1084,7 +1076,7 @@ static void streamDebug(QDebug dbg, const QVariant &v)
dbg.nospace() << v.toFloat();
break;
case QMetaType::QObjectStar:
- dbg.nospace() << qVariantValue<QObject *>(v);
+ dbg.nospace() << qvariant_cast<QObject *>(v);
break;
case QVariant::Double:
dbg.nospace() << v.toDouble();
@@ -1245,7 +1237,7 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler;
conversion functions to data types defined in QtGui, such as
QColor, QImage, and QPixmap. In other words, there is no \c
toColor() function. Instead, you can use the QVariant::value() or
- the qVariantValue() template function. For example:
+ the qvariant_cast() template function. For example:
\snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 2
@@ -1360,12 +1352,12 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler;
Note that you have to pass the address of the variable you want stored.
- Usually, you never have to use this constructor, use qVariantFromValue()
+ Usually, you never have to use this constructor, use QVariant::fromValue()
instead to construct variants from the pointer types represented by
\c QMetaType::VoidStar, \c QMetaType::QObjectStar and
\c QMetaType::QWidgetStar.
- \sa qVariantFromValue(), Type
+ \sa QVariant::fromValue(), Type
*/
/*!
@@ -3074,10 +3066,6 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
\snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 4
- \warning This function is not available with MSVC 6. Use
- qVariantSetValue() instead if you need to support that version of
- the compiler.
-
\sa value(), fromValue(), canConvert()
*/
@@ -3095,10 +3083,6 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
\snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 5
- \warning This function is not available with MSVC 6. Use
- qVariantValue() or qvariant_cast() instead if you need to support
- that version of the compiler.
-
\sa setValue(), fromValue(), canConvert()
*/
@@ -3111,10 +3095,6 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
\snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 6
- \warning This function is not available with MSVC 6. Use
- qVariantCanConvert() instead if you need to support that version
- of the compiler.
-
\sa convert()
*/
@@ -3130,23 +3110,22 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
\note If you are working with custom types, you should use
the Q_DECLARE_METATYPE() macro to register your custom type.
- \warning This function is not available with MSVC 6. Use
- qVariantFromValue() instead if you need to support that version
- of the compiler.
-
\sa setValue(), value()
*/
/*!
\fn QVariant qVariantFromValue(const T &value)
\relates QVariant
+ \obsolete
Returns a variant containing a copy of the given \a value
with template type \c{T}.
- This function is equivalent to QVariant::fromValue(\a value). It
- is provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ This function is equivalent to QVariant::fromValue(\a value).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
For example, a QObject pointer can be stored in a variant with the
following code:
@@ -3158,13 +3137,16 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
/*! \fn void qVariantSetValue(QVariant &variant, const T &value)
\relates QVariant
+ \obsolete
Sets the contents of the given \a variant to a copy of the
\a value with the specified template type \c{T}.
- This function is equivalent to QVariant::setValue(\a value). It
- is provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ This function is equivalent to QVariant::setValue(\a value).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QVariant::setValue()
*/
@@ -3175,33 +3157,39 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
Returns the given \a value converted to the template type \c{T}.
- This function is equivalent to qVariantValue().
+ This function is equivalent to QVariant::value().
- \sa qVariantValue(), QVariant::value()
+ \sa QVariant::value()
*/
/*! \fn T qVariantValue(const QVariant &value)
\relates QVariant
+ \obsolete
Returns the given \a value converted to the template type \c{T}.
This function is equivalent to
- \l{QVariant::value()}{QVariant::value}<T>(\a value). It is
- provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ \l{QVariant::value()}{QVariant::value}<T>(\a value).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QVariant::value(), qvariant_cast()
*/
/*! \fn bool qVariantCanConvert(const QVariant &value)
\relates QVariant
+ \obsolete
Returns true if the given \a value can be converted to the
template type specified; otherwise returns false.
- This function is equivalent to QVariant::canConvert(\a value). It
- is provided as a work-around for MSVC 6, which doesn't support
- member template functions.
+ This function is equivalent to QVariant::canConvert(\a value).
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QVariant::canConvert()
*/
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index cb2825c90a..b2679548c8 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -83,19 +83,11 @@ class QUrl;
class QVariant;
class QVariantComparisonHelper;
-#ifndef QT_NO_MEMBER_TEMPLATES
template <typename T>
inline QVariant qVariantFromValue(const T &);
-template <typename T>
-inline void qVariantSetValue(QVariant &, const T &);
-
-template<typename T>
-inline T qVariantValue(const QVariant &);
-
template<typename T>
-inline bool qVariantCanConvert(const QVariant &);
-#endif
+inline T qvariant_cast(const QVariant &);
class Q_CORE_EXPORT QVariant
{
@@ -227,6 +219,10 @@ class Q_CORE_EXPORT QVariant
QVariant(Qt::GlobalColor color);
QVariant& operator=(const QVariant &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QVariant &operator=(QVariant &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
Type type() const;
int userType() const;
@@ -327,13 +323,12 @@ class Q_CORE_EXPORT QVariant
const void *constData() const;
inline const void *data() const { return constData(); }
-#ifndef QT_NO_MEMBER_TEMPLATES
template<typename T>
inline void setValue(const T &value);
template<typename T>
inline T value() const
- { return qVariantValue<T>(*this); }
+ { return qvariant_cast<T>(*this); }
template<typename T>
static inline QVariant fromValue(const T &value)
@@ -341,8 +336,7 @@ class Q_CORE_EXPORT QVariant
template<typename T>
bool canConvert() const
- { return qVariantCanConvert<T>(*this); }
-#endif
+ { return canConvert(Type(qMetaTypeId<T>())); }
public:
#ifndef qdoc
@@ -527,11 +521,9 @@ inline QSize &QVariant::asSize()
{ return *reinterpret_cast<QSize *>(castOrDetach(Size)); }
#endif //QT3_SUPPORT
-#ifndef QT_NO_MEMBER_TEMPLATES
template<typename T>
inline void QVariant::setValue(const T &avalue)
{ qVariantSetValue(*this, avalue); }
-#endif
#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
@@ -594,16 +586,16 @@ template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
return v;
}
+#ifdef QT_DEPRECATED
template<typename T>
-inline T qVariantValue(const QVariant &variant)
+inline QT_DEPRECATED T qVariantValue(const QVariant &variant)
{ return qvariant_cast<T>(variant); }
template<typename T>
-inline bool qVariantCanConvert(const QVariant &variant)
-{
- return variant.canConvert(static_cast<QVariant::Type>(
- qMetaTypeId<T>(static_cast<T *>(0))));
-}
+inline QT_DEPRECATED bool qVariantCanConvert(const QVariant &variant)
+{ return variant.template canConvert<T>(); }
+#endif
+
#endif
Q_DECLARE_SHARED(QVariant)
Q_DECLARE_TYPEINFO(QVariant, Q_MOVABLE_TYPE);
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index ba8635361e..50b005d5d0 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -8,13 +8,15 @@ HEADERS += \
plugin/qplugin.h \
plugin/quuid.h \
plugin/qfactoryloader_p.h \
- plugin/qsystemlibrary_p.h
+ plugin/qsystemlibrary_p.h \
+ plugin/qelfparser_p.h
SOURCES += \
plugin/qpluginloader.cpp \
plugin/qfactoryloader.cpp \
plugin/quuid.cpp \
- plugin/qlibrary.cpp
+ plugin/qlibrary.cpp \
+ plugin/qelfparser_p.cpp
win32 {
SOURCES += \
diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp
new file mode 100644
index 0000000000..2e77ae7be8
--- /dev/null
+++ b/src/corelib/plugin/qelfparser_p.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module 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 "qlibrary_p.h"
+#include "qelfparser_p.h"
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+// #define QELFPARSER_DEBUG 1
+
+const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *sh)
+{
+ sh->name = read<qelfword_t>(data);
+ data += sizeof(qelfword_t); // sh_name
+ sh->type = read<qelfword_t>(data);
+ data += sizeof(qelfword_t) // sh_type
+ + sizeof(qelfaddr_t) // sh_flags
+ + sizeof(qelfaddr_t); // sh_addr
+ sh->offset = read<qelfoff_t>(data);
+ data += sizeof(qelfoff_t); // sh_offset
+ sh->size = read<qelfword_t>(data);
+ data += sizeof(qelfword_t); // sh_size
+ return data;
+}
+
+int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen)
+{
+#if defined(QELFPARSER_DEBUG)
+ qDebug() << "QElfParser::parse " << library;
+#endif
+
+ if (fdlen < 64){
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is not an ELF object (%2)").arg(library).arg(QLatin1String("file too small"));
+ return NotElf;
+ }
+ const char *data = dataStart;
+ if (qstrncmp(data, "\177ELF", 4) != 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is not an ELF object").arg(library);
+ return NotElf;
+ }
+ // 32 or 64 bit
+ if (data[4] != 1 && data[4] != 2) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd cpu architecture"));
+ return Corrupt;
+ }
+ m_bits = (data[4] << 5);
+
+ /* If you remove this check, to read ELF objects of a different arch, please make sure you modify the typedefs
+ to match the _plugin_ architecture.
+ */
+ if ((sizeof(void*) == 4 && m_bits != 32) || (sizeof(void*) == 8 && m_bits != 64)) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("wrong cpu architecture"));
+ return Corrupt;
+ }
+ // endian
+ if (data[5] == 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd endianess"));
+ return Corrupt;
+ }
+ m_endian = (data[5] == 1 ? ElfLittleEndian : ElfBigEndian);
+
+ data += 16 // e_ident
+ + sizeof(qelfhalf_t) // e_type
+ + sizeof(qelfhalf_t) // e_machine
+ + sizeof(qelfword_t) // e_version
+ + sizeof(qelfaddr_t) // e_entry
+ + sizeof(qelfoff_t); // e_phoff
+
+ qelfoff_t e_shoff = read<qelfoff_t> (data);
+ data += sizeof(qelfoff_t) // e_shoff
+ + sizeof(qelfword_t); // e_flags
+
+ qelfhalf_t e_shsize = read<qelfhalf_t> (data);
+
+ if (e_shsize > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shsize"));
+ return Corrupt;
+ }
+
+ data += sizeof(qelfhalf_t) // e_ehsize
+ + sizeof(qelfhalf_t) // e_phentsize
+ + sizeof(qelfhalf_t); // e_phnum
+
+ qelfhalf_t e_shentsize = read<qelfhalf_t> (data);
+
+ if (e_shentsize % 4){
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shentsize"));
+ return Corrupt;
+ }
+ data += sizeof(qelfhalf_t); // e_shentsize
+ qelfhalf_t e_shnum = read<qelfhalf_t> (data);
+ data += sizeof(qelfhalf_t); // e_shnum
+ qelfhalf_t e_shtrndx = read<qelfhalf_t> (data);
+ data += sizeof(qelfhalf_t); // e_shtrndx
+
+ if ((e_shnum * e_shentsize) > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("announced %2 sections, each %3 bytes, exceed file size"))
+ .arg(e_shnum).arg(e_shentsize);
+ return Corrupt;
+ }
+
+#if defined(QELFPARSER_DEBUG)
+ qDebug() << e_shnum << "sections starting at " << ("0x" + QByteArray::number(e_shoff, 16)).data() << "each" << e_shentsize << "bytes";
+#endif
+
+ ElfSectionHeader strtab;
+ qulonglong soff = e_shoff + e_shentsize * (e_shtrndx);
+
+ if ((soff + e_shentsize) > fdlen || soff % 4 || soff == 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("shstrtab section header seems to be at %1"))
+ .arg(QString::number(soff, 16));
+ return Corrupt;
+ }
+
+ parseSectionHeader(dataStart + soff, &strtab);
+ m_stringTableFileOffset = strtab.offset;
+
+ if ((m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("string table seems to be at %1"))
+ .arg(QString::number(soff, 16));
+ return Corrupt;
+ }
+
+#if defined(QELFPARSER_DEBUG)
+ qDebug(".shstrtab at 0x%s", QByteArray::number(m_stringTableFileOffset, 16).data());
+#endif
+
+ const char *s = dataStart + e_shoff;
+ for (int i = 0; i < e_shnum; ++i) {
+ ElfSectionHeader sh;
+ parseSectionHeader(s, &sh);
+ if (sh.name == 0) {
+ s += e_shentsize;
+ continue;
+ }
+ const char *shnam = dataStart + m_stringTableFileOffset + sh.name;
+
+ if (m_stringTableFileOffset + sh.name > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("section name %2 of %3 behind end of file"))
+ .arg(i).arg(e_shnum);
+ return Corrupt;
+ }
+
+#if defined(QELFPARSER_DEBUG)
+ qDebug() << "++++" << i << shnam;
+#endif
+
+ if (qstrcmp(shnam, ".qtplugin") == 0 || qstrcmp(shnam, ".rodata") == 0) {
+ if (!(sh.type & 0x1)) {
+ if (shnam[1] == 'r') {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("empty .rodata. not a library."));
+ return Corrupt;
+ }
+#if defined(QELFPARSER_DEBUG)
+ qDebug()<<"section is not program data. skipped.";
+#endif
+ s += e_shentsize;
+ continue;
+ }
+
+ if (sh.offset == 0 || (sh.offset + sh.size) > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("missing section data. This is not a library."));
+ return Corrupt;
+ }
+ *pos = sh.offset;
+ *sectionlen = sh.size - 1;
+ if (shnam[1] == 'q')
+ return Ok;
+ }
+ s += e_shentsize;
+ }
+ return NoQtSection;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/corelib/plugin/qelfparser_p.h b/src/corelib/plugin/qelfparser_p.h
new file mode 100644
index 0000000000..380d5a1e16
--- /dev/null
+++ b/src/corelib/plugin/qelfparser_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module 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 QELFPARSER_P_H
+#define QELFPARSER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qendian.h>
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QLibraryPrivate;
+
+typedef quint16 qelfhalf_t;
+typedef quint32 qelfword_t;
+typedef quintptr qelfoff_t;
+typedef quintptr qelfaddr_t;
+
+class QElfParser
+{
+public:
+ enum {Ok = 0, NotElf = 1, NoQtSection = 2, Corrupt = 3};
+ enum {ElfLittleEndian = 0, ElfBigEndian = 1};
+
+ struct ElfSectionHeader
+ {
+ qelfword_t name;
+ qelfword_t type;
+ qelfoff_t offset;
+ qelfword_t size;
+ };
+
+ int m_endian;
+ int m_bits;
+ int m_stringTableFileOffset;
+
+ template <typename T>
+ T read(const char *s)
+ {
+ if (m_endian == ElfBigEndian)
+ return qFromBigEndian<T>(reinterpret_cast<const uchar *>(s));
+ else
+ return qFromLittleEndian<T>(reinterpret_cast<const uchar *>(s));
+ }
+
+ const char *parseSectionHeader(const char* s, ElfSectionHeader *sh);
+ int parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen);
+};
+
+QT_END_NAMESPACE
+
+#endif // QELFPARSER_P_H
+
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 1874a9ed3b..239509e49a 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -38,7 +38,6 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#include "qplatformdefs.h"
#include "qlibrary.h"
@@ -61,11 +60,10 @@
#include <qdebug.h>
#include <qvector.h>
#include <qdir.h>
+#include "qelfparser_p.h"
QT_BEGIN_NAMESPACE
-//#define QT_DEBUG_COMPONENT
-
#ifdef QT_NO_DEBUG
# define QLIBRARY_AS_DEBUG false
#else
@@ -365,11 +363,35 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
fdlen = data.size();
}
- // verify that the pattern is present in the plugin
+ /*
+ ELF binaries on GNU, have .qplugin sections.
+ */
+ long pos = 0;
const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA";
const ulong plen = qstrlen(pattern);
- long pos = qt_find_pattern(filedata, fdlen, pattern, plen);
-
+#if defined (Q_OF_ELF) && defined(Q_CC_GNU)
+ int r = QElfParser().parse(filedata, fdlen, library, lib, &pos, &fdlen);
+ if (r == QElfParser::NoQtSection) {
+ if (pos > 0) {
+ // find inside .rodata
+ long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
+ if (rel < 0) {
+ pos = -1;
+ } else {
+ pos += rel;
+ }
+ } else {
+ pos = qt_find_pattern(filedata, fdlen, pattern, plen);
+ }
+ } else if (r != QElfParser::Ok) {
+ if (lib && qt_debug_component()) {
+ qWarning(qPrintable(lib->errorString));
+ }
+ return false;
+ }
+#else
+ pos = qt_find_pattern(filedata, fdlen, pattern, plen);
+#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
bool ret = false;
if (pos >= 0)
ret = qt_parse_pattern(filedata + pos, version, debug, key);
@@ -388,10 +410,14 @@ struct LibraryData {
LibraryData() : settings(0) { }
~LibraryData() {
delete settings;
+ foreach(QLibraryPrivate *lib, loadedLibs) {
+ lib->unload();
+ }
}
QSettings *settings;
LibraryMap libraryMap;
+ QSet<QLibraryPrivate*> loadedLibs;
};
Q_GLOBAL_STATIC(LibraryData, libraryData)
@@ -443,7 +469,18 @@ bool QLibraryPrivate::load()
return true;
if (fileName.isEmpty())
return false;
- return load_sys();
+
+ bool ret = load_sys();
+ if (ret) {
+ //when loading a library we add a reference to it so that the QLibraryPrivate won't get deleted
+ //this allows to unload the library at a later time
+ if (LibraryData *lib = libraryData()) {
+ lib->loadedLibs += this;
+ libraryRefCount.ref();
+ }
+ }
+
+ return ret;
}
bool QLibraryPrivate::unload()
@@ -451,10 +488,16 @@ bool QLibraryPrivate::unload()
if (!pHnd)
return false;
if (!libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to
- if (instance)
- delete instance();
+ delete inst.data();
if (unload_sys()) {
- instance = 0;
+ if (qt_debug_component())
+ qWarning() << "QLibraryPrivate::unload succeeded on" << fileName;
+ //when the library is unloaded, we release the reference on it so that 'this'
+ //can get deleted
+ if (LibraryData *lib = libraryData()) {
+ if (lib->loadedLibs.remove(this))
+ libraryRefCount.deref();
+ }
pHnd = 0;
}
}
@@ -496,7 +539,7 @@ bool QLibraryPrivate::loadPlugin()
\table
\header \i Platform \i Valid suffixes
- \row \i Windows \i \c .dll
+ \row \i Windows \i \c .dll, \c .DLL
\row \i Unix/Linux \i \c .so
\row \i AIX \i \c .a
\row \i HP-UX \i \c .sl, \c .so (HP-UXi)
@@ -509,7 +552,7 @@ bool QLibraryPrivate::loadPlugin()
bool QLibrary::isLibrary(const QString &fileName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- return fileName.endsWith(QLatin1String(".dll"));
+ return fileName.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive);
#elif defined(Q_OS_SYMBIAN)
// Plugin stubs are also considered libraries in Symbian.
return (fileName.endsWith(QLatin1String(".dll")) ||
@@ -571,6 +614,46 @@ bool QLibrary::isLibrary(const QString &fileName)
}
+#if defined (Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_CC_INTEL)
+#define QT_USE_MS_STD_EXCEPTION 1
+const char* qt_try_versioninfo(void *pfn, bool *exceptionThrown)
+{
+ *exceptionThrown = false;
+ const char *szData = 0;
+ typedef const char * (*VerificationFunction)();
+ VerificationFunction func = reinterpret_cast<VerificationFunction>(pfn);
+ __try {
+ if(func)
+ szData = func();
+ } __except(EXCEPTION_EXECUTE_HANDLER) {
+ *exceptionThrown = true;
+ }
+ return szData;
+}
+#endif
+
+#ifdef Q_CC_BOR
+typedef const char * __stdcall (*QtPluginQueryVerificationDataFunction)();
+#else
+typedef const char * (*QtPluginQueryVerificationDataFunction)();
+#endif
+
+bool qt_get_verificationdata(QtPluginQueryVerificationDataFunction pfn, uint *qt_version, bool *debug, QByteArray *key, bool *exceptionThrown)
+{
+ *exceptionThrown = false;
+ const char *szData = 0;
+ if (!pfn)
+ return false;
+#ifdef QT_USE_MS_STD_EXCEPTION
+ szData = qt_try_versioninfo((void *)pfn, exceptionThrown);
+ if (*exceptionThrown)
+ return false;
+#else
+ szData = pfn();
+#endif
+ return qt_parse_pattern(szData, qt_version, debug, key);
+}
+
bool QLibraryPrivate::isPlugin(QSettings *settings)
{
errorString.clear();
@@ -646,70 +729,82 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
} else
#endif
{
- bool temporary_load = false;
+ bool retryLoadLibrary = false; // Only used on Windows with MS compiler.(false in other cases)
+ do {
+ bool temporary_load = false;
#ifdef Q_OS_WIN
- HMODULE hTempModule = 0;
+ HMODULE hTempModule = 0;
#endif
- if (!pHnd) {
+ if (!pHnd) {
#ifdef Q_OS_WIN
- //avoid 'Bad Image' message box
- UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
- hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, DONT_RESOLVE_DLL_REFERENCES);
- SetErrorMode(oldmode);
+ DWORD dwFlags = (retryLoadLibrary) ? 0: DONT_RESOLVE_DLL_REFERENCES;
+ //avoid 'Bad Image' message box
+ UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+ hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, dwFlags);
+ SetErrorMode(oldmode);
#else
# if defined(Q_OS_SYMBIAN)
- //Guard against accidentally trying to load non-plugin libraries by making sure the stub exists
- if (fileinfo.exists())
+ //Guard against accidentally trying to load non-plugin libraries by making sure the stub exists
+ if (fileinfo.exists())
# endif
- temporary_load = load_sys();
+ temporary_load = load_sys();
#endif
- }
-# ifdef Q_CC_BOR
- typedef const char * __stdcall (*QtPluginQueryVerificationDataFunction)();
-# else
- typedef const char * (*QtPluginQueryVerificationDataFunction)();
-# endif
+ }
#ifdef Q_OS_WIN
- QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = hTempModule
- ? (QtPluginQueryVerificationDataFunction)
+ QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = hTempModule ? (QtPluginQueryVerificationDataFunction)
#ifdef Q_OS_WINCE
- ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data")
+ ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data")
#else
- ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data")
+ ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data")
#endif
: (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
#else
- QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL;
+ QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL;
# if defined(Q_OS_SYMBIAN)
- if (temporary_load) {
- qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
- // If resolving with function name failed (i.e. not STDDLL), try resolving using known ordinal
- if (!qtPluginQueryVerificationDataFunction)
- qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("1");
- }
+ if (temporary_load) {
+ qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
+ // If resolving with function name failed (i.e. not STDDLL), try resolving using known ordinal
+ if (!qtPluginQueryVerificationDataFunction)
+ qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("1");
+ }
# else
- qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
+ qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
# endif
#endif
-
- if (!qtPluginQueryVerificationDataFunction
- || !qt_parse_pattern(qtPluginQueryVerificationDataFunction(), &qt_version, &debug, &key)) {
- qt_version = 0;
- key = "unknown";
- if (temporary_load)
- unload_sys();
- } else {
- success = true;
- }
-#ifdef Q_OS_WIN
- if (hTempModule) {
- BOOL ok = ::FreeLibrary(hTempModule);
- if (ok) {
- hTempModule = 0;
+ bool exceptionThrown = false;
+ bool ret = qt_get_verificationdata(qtPluginQueryVerificationDataFunction,
+ &qt_version, &debug, &key, &exceptionThrown);
+ if (!exceptionThrown) {
+ if (!ret) {
+ qt_version = 0;
+ key = "unknown";
+ if (temporary_load)
+ unload_sys();
+ } else {
+ success = true;
+ }
+ retryLoadLibrary = false;
+ }
+#ifdef QT_USE_MS_STD_EXCEPTION
+ else {
+ // An exception was thrown when calling qt_plugin_query_verification_data().
+ // This usually happens when plugin is compiled with the /clr compiler flag,
+ // & will only work if the dependencies are loaded & DLLMain() is called.
+ // LoadLibrary() will do this, try once with this & if it fails dont load.
+ retryLoadLibrary = !retryLoadLibrary;
}
+#endif
+#ifdef Q_OS_WIN
+ if (hTempModule) {
+ BOOL ok = ::FreeLibrary(hTempModule);
+ if (ok) {
+ hTempModule = 0;
+ }
- }
+ }
#endif
+ } while(retryLoadLibrary); // Will be 'false' in all cases other than when an
+ // exception is thrown(will happen only when using a MS compiler)
}
// Qt 4.5 compatibility: stl doesn't affect binary compatibility
@@ -1039,7 +1134,7 @@ void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &ver
*/
void *QLibrary::resolve(const char *symbol)
{
- if (!load())
+ if (!isLoaded() && !load())
return 0;
return d->resolve(symbol);
}
@@ -1182,15 +1277,11 @@ QLibrary::LoadHints QLibrary::loadHints() const
/* Internal, for debugging */
bool qt_debug_component()
{
-#if defined(QT_DEBUG_COMPONENT)
- return true; //compatibility?
-#else
static int debug_env = -1;
if (debug_env == -1)
debug_env = QT_PREPEND_NAMESPACE(qgetenv)("QT_DEBUG_PLUGINS").toInt();
return debug_env != 0;
-#endif
}
QT_END_NAMESPACE
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index 02dc523d89..b73fce50be 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -60,6 +60,7 @@
#include "QtCore/qpointer.h"
#include "QtCore/qstringlist.h"
#include "QtCore/qplugin.h"
+#include "QtCore/qsharedpointer.h"
#ifndef QT_NO_LIBRARY
@@ -90,6 +91,7 @@ public:
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString());
+ QWeakPointer<QObject> inst;
QtPluginInstanceFunction instance;
uint qt_version;
QString lastModified;
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index e8f0eaec40..9ad1c01f49 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -223,11 +223,15 @@ bool QLibraryPrivate::load_sys()
#ifdef Q_OS_MAC
if (!pHnd) {
- if (CFBundleRef bundle = CFBundleGetBundleWithIdentifier(QCFString(fileName))) {
+ QByteArray utf8Bundle = fileName.toUtf8();
+ QCFType<CFURLRef> bundleUrl = CFURLCreateFromFileSystemRepresentation(NULL, reinterpret_cast<const UInt8*>(utf8Bundle.data()), utf8Bundle.length(), true);
+ QCFType<CFBundleRef> bundle = CFBundleCreate(NULL, bundleUrl);
+ if(bundle) {
QCFType<CFURLRef> url = CFBundleCopyExecutableURL(bundle);
- QCFString str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
- pHnd = dlopen(QFile::encodeName(str), dlFlags);
- attempt = str;
+ char executableFile[FILENAME_MAX];
+ CFURLGetFileSystemRepresentation(url, true, reinterpret_cast<UInt8*>(executableFile), FILENAME_MAX);
+ attempt = QString::fromUtf8(executableFile);
+ pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
}
}
#endif
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index 7f541f1c59..bd49b15cf7 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -101,13 +101,17 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
// NOTE: if you change pattern, you MUST change the pattern in
// qlibrary.cpp as well. changing the pattern will break all
// backwards compatibility as well (no old plugins will be loaded).
+// QT5: should probably remove the entire pattern thing and do the section
+// trick for all platforms. for now, keep it and fallback to scan for it.
# ifdef QPLUGIN_DEBUG_STR
# undef QPLUGIN_DEBUG_STR
# endif
# ifdef QT_NO_DEBUG
# define QPLUGIN_DEBUG_STR "false"
+# define QPLUGIN_SECTION_DEBUG_STR ""
# else
# define QPLUGIN_DEBUG_STR "true"
+# define QPLUGIN_SECTION_DEBUG_STR ".debug"
# endif
# define Q_PLUGIN_VERIFICATION_DATA \
static const char qt_plugin_verification_data[] = \
@@ -116,6 +120,13 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
"debug="QPLUGIN_DEBUG_STR"\n" \
"buildkey="QT_BUILD_KEY;
+# if defined (Q_OF_ELF) && defined (Q_CC_GNU)
+# define Q_PLUGIN_VERIFICATION_SECTION \
+ __attribute__ ((section (".qtplugin"))) __attribute__((used))
+# else
+# define Q_PLUGIN_VERIFICATION_SECTION
+# endif
+
# if defined (Q_OS_WIN32) && defined(Q_CC_BOR)
# define Q_STANDARD_CALL __stdcall
# else
@@ -123,7 +134,7 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
# endif
# define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS) \
- Q_PLUGIN_VERIFICATION_DATA \
+ Q_PLUGIN_VERIFICATION_SECTION Q_PLUGIN_VERIFICATION_DATA \
Q_EXTERN_C Q_DECL_EXPORT \
const char * Q_STANDARD_CALL qt_plugin_query_verification_data() \
{ return qt_plugin_verification_data; } \
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index b1d1eccdcf..9f322df61f 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -198,11 +198,11 @@ QPluginLoader::~QPluginLoader()
*/
QObject *QPluginLoader::instance()
{
- if (!load())
+ if (!isLoaded() && !load())
return 0;
- if (d->instance)
- return d->instance();
- return 0;
+ if (!d->inst && d->instance)
+ d->inst = d->instance();
+ return d->inst.data();
}
/*!
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 4b371f7067..d704615b9c 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -793,7 +793,7 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr
}
// We require that at least one animation is valid.
// ### generalize
- QList<QVariantAnimation*> variantAnims = qFindChildren<QVariantAnimation*>(anim);
+ QList<QVariantAnimation*> variantAnims = anim->findChildren<QVariantAnimation*>();
if (QVariantAnimation *va = qobject_cast<QVariantAnimation*>(anim))
variantAnims.append(va);
@@ -1178,7 +1178,7 @@ void QStateMachinePrivate::removeStartState()
void QStateMachinePrivate::clearHistory()
{
Q_Q(QStateMachine);
- QList<QHistoryState*> historyStates = qFindChildren<QHistoryState*>(q);
+ QList<QHistoryState*> historyStates = q->findChildren<QHistoryState*>();
for (int i = 0; i < historyStates.size(); ++i) {
QHistoryState *h = historyStates.at(i);
QHistoryStatePrivate::get(h)->configuration.clear();
@@ -1440,7 +1440,7 @@ void QStateMachinePrivate::goToState(QAbstractState *targetState)
Q_ASSERT(sourceState != 0);
// Reuse previous GoToStateTransition in case of several calls to
// goToState() in a row.
- GoToStateTransition *trans = qFindChild<GoToStateTransition*>(sourceState);
+ GoToStateTransition *trans = sourceState->findChild<GoToStateTransition*>();
if (!trans) {
trans = new GoToStateTransition(targetState);
sourceState->addTransition(trans);
@@ -1562,7 +1562,7 @@ void QStateMachinePrivate::unregisterAllTransitions()
{
Q_Q(QStateMachine);
{
- QList<QSignalTransition*> transitions = qFindChildren<QSignalTransition*>(rootState());
+ QList<QSignalTransition*> transitions = rootState()->findChildren<QSignalTransition*>();
for (int i = 0; i < transitions.size(); ++i) {
QSignalTransition *t = transitions.at(i);
if (t->machine() == q)
@@ -1570,7 +1570,7 @@ void QStateMachinePrivate::unregisterAllTransitions()
}
}
{
- QList<QEventTransition*> transitions = qFindChildren<QEventTransition*>(rootState());
+ QList<QEventTransition*> transitions = rootState()->findChildren<QEventTransition*>();
for (int i = 0; i < transitions.size(); ++i) {
QEventTransition *t = transitions.at(i);
if (t->machine() == q)
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 43df13acca..b85a22d22d 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -130,7 +130,7 @@ QMutex::QMutex(RecursionMode mode)
\warning Destroying a locked mutex may result in undefined behavior.
*/
QMutex::~QMutex()
-{ delete d; }
+{ delete static_cast<QMutexPrivate *>(d); }
/*!
Locks the mutex. If another thread has locked the mutex then this
@@ -146,6 +146,7 @@ QMutex::~QMutex()
*/
void QMutex::lock()
{
+ QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
Qt::HANDLE self;
if (d->recursive) {
@@ -158,11 +159,6 @@ void QMutex::lock()
bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0;
if (!isLocked) {
-#ifndef QT_NO_DEBUG
- if (d->owner == self)
- qWarning() << "QMutex::lock: Deadlock detected in thread" << d->owner;
-#endif
-
// didn't get the lock, wait for it
isLocked = d->wait();
Q_ASSERT_X(isLocked, "QMutex::lock",
@@ -178,54 +174,11 @@ void QMutex::lock()
return;
}
-#ifndef QT_NO_DEBUG
- self = QThread::currentThreadId();
-#endif
bool isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1);
if (!isLocked) {
- int spinCount = 0;
- int lastSpinCount = d->lastSpinCount;
-
- enum { AdditionalSpins = 20, SpinCountPenalizationDivisor = 4 };
- const int maximumSpinCount = lastSpinCount + AdditionalSpins;
-
- do {
- if (spinCount++ > maximumSpinCount) {
- // puts("spinning useless, sleeping");
- isLocked = d->contenders.fetchAndAddAcquire(1) == 0;
- if (!isLocked) {
-#ifndef QT_NO_DEBUG
- if (d->owner == self)
- qWarning() << "QMutex::lock: Deadlock detected in thread" << d->owner;
-#endif
-
- // didn't get the lock, wait for it
- isLocked = d->wait();
- Q_ASSERT_X(isLocked, "QMutex::lock",
- "Internal error, infinite wait has timed out.");
-
- // don't need to wait for the lock anymore
- d->contenders.deref();
- }
- // decrease the lastSpinCount since we didn't actually get the lock by spinning
- spinCount = -d->lastSpinCount / SpinCountPenalizationDivisor;
- break;
- }
-
- isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1);
- } while (!isLocked);
-
- // adjust the last spin lock count
- lastSpinCount = d->lastSpinCount;
- d->lastSpinCount = spinCount >= 0
- ? qMax(lastSpinCount, spinCount)
- : lastSpinCount + spinCount;
+ lockInternal();
}
-
-#ifndef QT_NO_DEBUG
- d->owner = self;
-#endif
}
/*!
@@ -247,6 +200,7 @@ void QMutex::lock()
*/
bool QMutex::tryLock()
{
+ QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
Qt::HANDLE self;
if (d->recursive) {
@@ -270,18 +224,12 @@ bool QMutex::tryLock()
return isLocked;
}
-#ifndef QT_NO_DEBUG
- self = QThread::currentThreadId();
-#endif
bool isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1);
if (!isLocked) {
// some other thread has the mutex locked, or we tried to
// recursively lock an non-recursive mutex
return isLocked;
}
-#ifndef QT_NO_DEBUG
- d->owner = self;
-#endif
return isLocked;
}
@@ -310,6 +258,7 @@ bool QMutex::tryLock()
*/
bool QMutex::tryLock(int timeout)
{
+ QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
Qt::HANDLE self;
if (d->recursive) {
@@ -337,9 +286,6 @@ bool QMutex::tryLock(int timeout)
return true;
}
-#ifndef QT_NO_DEBUG
- self = QThread::currentThreadId();
-#endif
bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0;
if (!isLocked) {
// didn't get the lock, wait for it
@@ -350,9 +296,6 @@ bool QMutex::tryLock(int timeout)
if (!isLocked)
return false;
}
-#ifndef QT_NO_DEBUG
- d->owner = self;
-#endif
return true;
}
@@ -366,8 +309,7 @@ bool QMutex::tryLock(int timeout)
*/
void QMutex::unlock()
{
- Q_ASSERT_X(d->owner == QThread::currentThreadId(), "QMutex::unlock()",
- "A mutex must be unlocked in the same thread that locked it.");
+ QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
if (d->recursive) {
if (!--d->count) {
@@ -376,9 +318,6 @@ void QMutex::unlock()
d->wakeUp();
}
} else {
-#ifndef QT_NO_DEBUG
- d->owner = 0;
-#endif
if (!d->contenders.testAndSetRelease(1, 0))
d->wakeUp();
}
@@ -506,6 +445,72 @@ void QMutex::unlock()
Use the constructor that takes a RecursionMode parameter instead.
*/
+/*!
+ \internal helper for lockInline()
+ */
+void QMutex::lockInternal()
+{
+ QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
+ int spinCount = 0;
+ int lastSpinCount = d->lastSpinCount;
+
+ enum { AdditionalSpins = 20, SpinCountPenalizationDivisor = 4 };
+ const int maximumSpinCount = lastSpinCount + AdditionalSpins;
+
+ do {
+ if (spinCount++ > maximumSpinCount) {
+ // puts("spinning useless, sleeping");
+ bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0;
+ if (!isLocked) {
+
+ // didn't get the lock, wait for it
+ isLocked = d->wait();
+ Q_ASSERT_X(isLocked, "QMutex::lock",
+ "Internal error, infinite wait has timed out.");
+
+ // don't need to wait for the lock anymore
+ d->contenders.deref();
+ }
+ // decrease the lastSpinCount since we didn't actually get the lock by spinning
+ spinCount = -d->lastSpinCount / SpinCountPenalizationDivisor;
+ break;
+ }
+ } while (d->contenders != 0 || !d->contenders.testAndSetAcquire(0, 1));
+
+ // adjust the last spin lock count
+ lastSpinCount = d->lastSpinCount;
+ d->lastSpinCount = spinCount >= 0
+ ? qMax(lastSpinCount, spinCount)
+ : lastSpinCount + spinCount;
+}
+
+/*!
+ \internal
+*/
+void QMutex::unlockInternal()
+{
+ static_cast<QMutexPrivate *>(d)->wakeUp();
+}
+
+/*!
+ \fn QMutex::lockInline()
+ \internal
+ inline version of QMutex::lock()
+*/
+
+/*!
+ \fn QMutex::unlockInline()
+ \internal
+ inline version of QMutex::unlock()
+*/
+
+/*!
+ \fn QMutex::tryLockInline()
+ \internal
+ inline version of QMutex::tryLock()
+*/
+
+
QT_END_NAMESPACE
#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 509f300862..710b794bb9 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -43,6 +43,7 @@
#define QMUTEX_H
#include <QtCore/qglobal.h>
+#include <QtCore/qatomic.h>
#include <new>
QT_BEGIN_HEADER
@@ -53,7 +54,8 @@ QT_MODULE(Core)
#ifndef QT_NO_THREAD
-class QMutexPrivate;
+class QAtomicInt;
+class QMutexData;
class Q_CORE_EXPORT QMutex
{
@@ -66,10 +68,13 @@ public:
explicit QMutex(RecursionMode mode = NonRecursive);
~QMutex();
- void lock();
- bool tryLock();
+ void lock(); //### Qt5: make inline;
+ inline void lockInline();
+ bool tryLock(); //### Qt5: make inline;
bool tryLock(int timeout);
- void unlock();
+ inline bool tryLockInline();
+ void unlock(); //### Qt5: make inline;
+ inline void unlockInline();
#if defined(QT3_SUPPORT)
inline QT3_SUPPORT bool locked()
@@ -86,9 +91,11 @@ public:
#endif
private:
+ void lockInternal();
+ void unlockInternal();
Q_DISABLE_COPY(QMutex)
- QMutexPrivate *d;
+ QMutexData *d;
};
class Q_CORE_EXPORT QMutexLocker
@@ -99,7 +106,7 @@ public:
Q_ASSERT_X((reinterpret_cast<quintptr>(m) & quintptr(1u)) == quintptr(0),
"QMutexLocker", "QMutex pointer is misaligned");
if (m) {
- m->lock();
+ m->lockInline();
val = reinterpret_cast<quintptr>(m) | quintptr(1u);
} else {
val = 0;
@@ -111,7 +118,7 @@ public:
{
if ((val & quintptr(1u)) == quintptr(1u)) {
val &= ~quintptr(1u);
- mutex()->unlock();
+ mutex()->unlockInline();
}
}
@@ -119,7 +126,7 @@ public:
{
if (val) {
if ((val & quintptr(1u)) == quintptr(0u)) {
- mutex()->lock();
+ mutex()->lockInline();
val |= quintptr(1u);
}
}
@@ -145,6 +152,46 @@ private:
quintptr val;
};
+class QMutexData
+{
+ public:
+ QAtomicInt contenders;
+ const uint recursive : 1;
+ uint reserved : 31;
+ protected:
+ QMutexData(QMutex::RecursionMode mode);
+ ~QMutexData();
+};
+
+inline void QMutex::unlockInline()
+{
+ if (d->recursive) {
+ unlock();
+ } else if (!d->contenders.testAndSetRelease(1, 0)) {
+ unlockInternal();
+ }
+}
+
+inline bool QMutex::tryLockInline()
+{
+ if (d->recursive) {
+ return tryLock();
+ } else {
+ return d->contenders.testAndSetAcquire(0, 1);
+ }
+}
+
+inline void QMutex::lockInline()
+{
+ if (d->recursive) {
+ lock();
+ } else if(!tryLockInline()) {
+ lockInternal();
+ }
+}
+
+
+
#else // QT_NO_THREAD
@@ -157,9 +204,11 @@ public:
inline ~QMutex() {}
static inline void lock() {}
- static inline bool tryLock() { return true; }
- static inline bool tryLock(int timeout) { Q_UNUSED(timeout); return true; }
- static void unlock() {}
+ static inline void lockInline() {}
+ static inline bool tryLock(int timeout = 0) { Q_UNUSED(timeout); return true; }
+ static inline bool tryLockInline() { return true; }
+ static inline void unlock() {}
+ static inline void unlockInline() {}
#if defined(QT3_SUPPORT)
static inline QT3_SUPPORT bool locked() { return false; }
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index dce162a6e7..6126423edf 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -56,10 +56,11 @@
#include <QtCore/qglobal.h>
#include <QtCore/qnamespace.h>
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
-class QMutexPrivate {
+class QMutexPrivate : public QMutexData {
public:
QMutexPrivate(QMutex::RecursionMode mode);
~QMutexPrivate();
@@ -68,8 +69,6 @@ public:
bool wait(int timeout = -1);
void wakeUp();
- const bool recursive;
- QAtomicInt contenders;
volatile int lastSpinCount;
Qt::HANDLE owner;
uint count;
@@ -83,6 +82,12 @@ public:
#endif
};
+inline QMutexData::QMutexData(QMutex::RecursionMode mode)
+ : recursive(mode == QMutex::Recursive)
+{}
+
+inline QMutexData::~QMutexData() {}
+
QT_END_NAMESPACE
#endif // QMUTEX_P_H
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index a58368c242..7e7ef22cc4 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -63,7 +63,7 @@ static void report_error(int code, const char *where, const char *what)
QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode)
- : recursive(mode == QMutex::Recursive), contenders(0), lastSpinCount(0), owner(0), count(0), wakeup(false)
+ : QMutexData(mode), lastSpinCount(0), owner(0), count(0), wakeup(false)
{
report_error(pthread_mutex_init(&mutex, NULL), "QMutex", "mutex init");
report_error(pthread_cond_init(&cond, NULL), "QMutex", "cv init");
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index 9d5895333b..a810000f18 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode)
- : recursive(mode == QMutex::Recursive), contenders(0), lastSpinCount(0), owner(0), count(0)
+ : QMutexData(mode), lastSpinCount(0), owner(0), count(0)
{
event = CreateEvent(0, FALSE, FALSE, 0);
if (!event)
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index 702125c257..375ded11e4 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -55,7 +55,7 @@
QT_BEGIN_NAMESPACE
-class QMutex;
+#include <QtCore/qmutex.h>
/*
Locks 2 mutexes in a defined order, avoiding a recursive lock if
@@ -79,8 +79,8 @@ public:
void relock()
{
if (!locked) {
- if (mtx1) mtx1->lock();
- if (mtx2) mtx2->lock();
+ if (mtx1) mtx1->lockInline();
+ if (mtx2) mtx2->lockInline();
locked = true;
}
}
@@ -88,8 +88,8 @@ public:
void unlock()
{
if (locked) {
- if (mtx1) mtx1->unlock();
- if (mtx2) mtx2->unlock();
+ if (mtx1) mtx1->unlockInline();
+ if (mtx2) mtx2->unlockInline();
locked = false;
}
}
@@ -100,10 +100,10 @@ public:
if (mtx1 == mtx2)
return false;
if (mtx1 < mtx2) {
- mtx2->lock();
+ mtx2->lockInline();
return true;
}
- if (!mtx2->tryLock()) {
+ if (!mtx2->tryLockInline()) {
mtx1->unlock();
mtx2->lock();
mtx1->lock();
diff --git a/src/corelib/thread/qthreadstorage.h b/src/corelib/thread/qthreadstorage.h
index 3a786ba5bb..6264674bb0 100644
--- a/src/corelib/thread/qthreadstorage.h
+++ b/src/corelib/thread/qthreadstorage.h
@@ -91,8 +91,6 @@ inline
void qThreadStorage_setLocalData(QThreadStorageData &d, T **t)
{ (void) d.set(*t); }
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
-
// value-based specialization
template <typename T>
inline
@@ -116,8 +114,6 @@ inline
void qThreadStorage_setLocalData(QThreadStorageData &d, T *t)
{ (void) d.set(new T(*t)); }
-#endif // QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
-
// MOC_SKIP_END
#endif
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
index 60cdc9ce87..bd79904ec6 100644
--- a/src/corelib/tools/qbitarray.h
+++ b/src/corelib/tools/qbitarray.h
@@ -63,6 +63,10 @@ public:
explicit QBitArray(int size, bool val = false);
QBitArray(const QBitArray &other) : d(other.d) {}
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QBitArray &operator=(QBitArray &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline int size() const { return (d.size() << 3) - *d.constData(); }
inline int count() const { return (d.size() << 3) - *d.constData(); }
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 033da90925..0a4aad2295 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -542,12 +542,14 @@ QByteArray qUncompress(const uchar* data, int nbytes)
forever {
ulong alloc = len;
- d.reset(q_check_ptr(static_cast<QByteArray::Data *>(qRealloc(d.take(), sizeof(QByteArray::Data) + alloc))));
- if (!d) {
+ QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + alloc));
+ if (!p) {
// we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS
qWarning("qUncompress: could not allocate enough memory to uncompress data");
return QByteArray();
}
+ d.take(); // realloc was successful
+ d.reset(p);
int res = ::uncompress((uchar*)d->array, &len,
(uchar*)data+4, nbytes-4);
@@ -555,12 +557,14 @@ QByteArray qUncompress(const uchar* data, int nbytes)
switch (res) {
case Z_OK:
if (len != alloc) {
- d.reset(q_check_ptr(static_cast<QByteArray::Data *>(qRealloc(d.take(), sizeof(QByteArray::Data) + len))));
- if (!d) {
+ QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + len));
+ if (!p) {
// we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS
qWarning("qUncompress: could not allocate enough memory to uncompress data");
return QByteArray();
}
+ d.take(); // realloc was successful
+ d.reset(p);
}
d->ref = 1;
d->alloc = d->size = len;
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index a3fe3f591a..3cdcaabd4e 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -144,6 +144,10 @@ public:
QByteArray &operator=(const QByteArray &);
QByteArray &operator=(const char *str);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QByteArray &operator=(QByteArray &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline int size() const;
bool isEmpty() const;
diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h
index 44477d7e5a..debab7d911 100644
--- a/src/corelib/tools/qcache.h
+++ b/src/corelib/tools/qcache.h
@@ -61,7 +61,7 @@ class QCache
};
Node *f, *l;
QHash<Key, Node> hash;
- void *unused;
+ void *unused; // ### Qt5: remove
int mx, total;
inline void unlink(Node &n) {
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index f767962195..4c1a846633 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -110,6 +110,10 @@ public:
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
QContiguousCache<T> &operator=(const QContiguousCache<T> &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QContiguousCache<T> &operator=(QContiguousCache<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
bool operator==(const QContiguousCache<T> &other) const;
inline bool operator!=(const QContiguousCache<T> &other) const { return !(*this == other); }
diff --git a/src/corelib/tools/qelapsedtimer.cpp b/src/corelib/tools/qelapsedtimer.cpp
index cb5e701af8..4adddf9bb9 100644
--- a/src/corelib/tools/qelapsedtimer.cpp
+++ b/src/corelib/tools/qelapsedtimer.cpp
@@ -136,10 +136,11 @@ QT_BEGIN_NAMESPACE
implementations, to guarantee that the same reference clock is being
used.
- \value SystemTime The human-readable system time. This clock is not monotonic.
- \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is monotonic and does not overflow.
- \value TickCounter The system's tick counter, used on Windows and Symbian systems. This clock may overflow.
- \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow.
+ \value SystemTime The human-readable system time. This clock is not monotonic.
+ \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is monotonic and does not overflow.
+ \value TickCounter The system's tick counter, used on Windows and Symbian systems. This clock may overflow.
+ \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow.
+ \value PerformanceCounter The high-resolution performance counter provided by Windows. This clock is monotonic and does not overflow.
\section2 SystemTime
@@ -163,7 +164,9 @@ QT_BEGIN_NAMESPACE
The tick counter clock type is based on the system's or the processor's
tick counter, multiplied by the duration of a tick. This clock type is
- used on Windows and Symbian platforms.
+ used on Windows and Symbian platforms. If the high-precision performance
+ counter is available on Windows, the \tt{PerformanceCounter} clock type
+ is used instead.
The TickCounter clock type is the only clock type that may overflow.
Windows Vista and Windows Server 2008 support the extended 64-bit tick
@@ -191,6 +194,16 @@ QT_BEGIN_NAMESPACE
This clock is monotonic and does not overflow.
+ \section2 PerformanceCounter
+
+ This clock uses the Windows functions \tt{QueryPerformanceCounter} and
+ \tt{QueryPerformanceFrequency} to access the system's high-precision
+ performance counter. Since this counter may not be available on all
+ systems, QElapsedTimer will fall back to the \tt{TickCounter} clock
+ automatically, if this clock cannot be used.
+
+ This clock is monotonic and does not overflow.
+
\sa clockType(), isMonotonic()
*/
diff --git a/src/corelib/tools/qelapsedtimer.h b/src/corelib/tools/qelapsedtimer.h
index 0d6f0be2c3..b996f6abab 100644
--- a/src/corelib/tools/qelapsedtimer.h
+++ b/src/corelib/tools/qelapsedtimer.h
@@ -57,7 +57,8 @@ public:
SystemTime,
MonotonicClock,
TickCounter,
- MachAbsoluteTime
+ MachAbsoluteTime,
+ PerformanceCounter
};
static ClockType clockType();
static bool isMonotonic();
diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp
index 135196acbe..c77acaa15f 100644
--- a/src/corelib/tools/qelapsedtimer_win.cpp
+++ b/src/corelib/tools/qelapsedtimer_win.cpp
@@ -42,6 +42,9 @@
#include "qelapsedtimer.h"
#include <windows.h>
+// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable
+static quint64 counterFrequency = 0;
+
typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void);
static PtrGetTickCount64 ptrGetTickCount64 = 0;
@@ -65,12 +68,44 @@ static void resolveLibs()
ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, "GetTickCount64");
#endif
+ // Retrieve the number of high-resolution performance counter ticks per second
+ LARGE_INTEGER frequency;
+ if (!QueryPerformanceFrequency(&frequency)) {
+ counterFrequency = 0;
+ } else {
+ counterFrequency = frequency.QuadPart;
+ }
+
done = true;
}
+static inline qint64 ticksToMilliseconds(qint64 ticks)
+{
+ if (counterFrequency > 0) {
+ // QueryPerformanceCounter uses an arbitrary frequency
+ return ticks * 1000 / counterFrequency;
+ } else {
+ // GetTickCount(64) return milliseconds
+ return ticks;
+ }
+}
+
static quint64 getTickCount()
{
resolveLibs();
+
+ // This avoids a division by zero and disables the high performance counter if it's not available
+ if (counterFrequency > 0) {
+ LARGE_INTEGER counter;
+
+ if (QueryPerformanceCounter(&counter)) {
+ return counter.QuadPart;
+ } else {
+ qWarning("QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded.");
+ return 0;
+ }
+ }
+
if (ptrGetTickCount64)
return ptrGetTickCount64();
@@ -85,7 +120,12 @@ static quint64 getTickCount()
QElapsedTimer::ClockType QElapsedTimer::clockType()
{
- return TickCounter;
+ resolveLibs();
+
+ if (counterFrequency > 0)
+ return PerformanceCounter;
+ else
+ return TickCounter;
}
bool QElapsedTimer::isMonotonic()
@@ -104,22 +144,24 @@ qint64 QElapsedTimer::restart()
qint64 oldt1 = t1;
t1 = getTickCount();
t2 = 0;
- return t1 - oldt1;
+ return ticksToMilliseconds(t1 - oldt1);
}
qint64 QElapsedTimer::elapsed() const
{
- return getTickCount() - t1;
+ qint64 elapsed = getTickCount() - t1;
+ return ticksToMilliseconds(elapsed);
}
qint64 QElapsedTimer::msecsSinceReference() const
{
- return t1;
+ return ticksToMilliseconds(t1);
}
qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const
{
- return other.t1 - t1;
+ qint64 difference = other.t1 - t1;
+ return ticksToMilliseconds(difference);
}
qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index c7e4bc14d5..992ff33b94 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -225,7 +225,7 @@ struct QHashNode
inline bool same_key(uint h0, const Key &key0) { return h0 == h && key0 == key; }
};
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
#define Q_HASH_DECLARE_INT_NODES(key_type) \
template <class T> \
struct QHashDummyNode<key_type, T> { \
@@ -253,7 +253,6 @@ Q_HASH_DECLARE_INT_NODES(ushort);
Q_HASH_DECLARE_INT_NODES(int);
Q_HASH_DECLARE_INT_NODES(uint);
#undef Q_HASH_DECLARE_INT_NODES
-#endif // QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
template <class Key, class T>
class QHash
@@ -284,6 +283,10 @@ public:
inline ~QHash() { if (!d->ref.deref()) freeData(d); }
QHash<Key, T> &operator=(const QHash<Key, T> &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QHash<Key, T> &operator=(QHash<Key, T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
bool operator==(const QHash<Key, T> &other) const;
inline bool operator!=(const QHash<Key, T> &other) const { return !(*this == other); }
@@ -513,8 +516,6 @@ Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode2(QHashData::Node *node)
{
#ifdef Q_CC_BOR
concrete(node)->~QHashNode<Key, T>();
-#elif defined(QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION)
- concrete(node)->~QHashNode();
#else
concrete(node)->~Node();
#endif
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index 9b3efa3aeb..c0879441fd 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -85,6 +85,10 @@ public:
inline QLinkedList(const QLinkedList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach(); }
~QLinkedList();
QLinkedList<T> &operator=(const QLinkedList<T> &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QLinkedList<T> &operator=(QLinkedList<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
bool operator==(const QLinkedList<T> &l) const;
inline bool operator!=(const QLinkedList<T> &l) const { return !(*this == l); }
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index d843cbeb32..8f988d60a2 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -50,6 +50,10 @@
#include <iterator>
#include <list>
#endif
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+#include <iterator>
+#include <initializer_list>
+#endif
#include <new>
#include <limits.h>
@@ -118,6 +122,14 @@ public:
inline QList(const QList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
~QList();
QList<T> &operator=(const QList<T> &l);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QList &operator=(QList &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ inline QList(std::initializer_list<T> args) : d(&QListData::shared_null)
+ { d->ref.ref(); qCopy(args.begin(), args.end(), std::back_inserter(*this)); }
+#endif
bool operator==(const QList<T> &l) const;
inline bool operator!=(const QList<T> &l) const { return !(*this == l); }
@@ -713,7 +725,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T>::~QList()
{
- if (d && !d->ref.deref())
+ if (!d->ref.deref())
free(d);
}
@@ -741,8 +753,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::free(QListData::Data *data)
{
node_destruct(reinterpret_cast<Node *>(data->array + data->begin),
reinterpret_cast<Node *>(data->array + data->end));
- if (data->ref == 0)
- qFree(data);
+ qFree(data);
}
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 1c2aad3dda..ce8fd75f7a 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -107,7 +107,6 @@ template <class Key> inline bool qMapLessThanKey(const Key &key1, const Key &key
return key1 < key2;
}
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
template <class Ptr> inline bool qMapLessThanKey(Ptr *key1, Ptr *key2)
{
Q_ASSERT(sizeof(quintptr) == sizeof(Ptr *));
@@ -119,7 +118,6 @@ template <class Ptr> inline bool qMapLessThanKey(const Ptr *key1, const Ptr *key
Q_ASSERT(sizeof(quintptr) == sizeof(const Ptr *));
return quintptr(key1) < quintptr(key2);
}
-#endif // QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
template <class Key, class T>
struct QMapNode {
@@ -187,6 +185,10 @@ public:
inline ~QMap() { if (!d) return; if (!d->ref.deref()) freeData(d); }
QMap<Key, T> &operator=(const QMap<Key, T> &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QMap<Key, T> &operator=(QMap<Key, T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
#ifndef QT_NO_STL
explicit QMap(const typename std::map<Key, T> &other);
std::map<Key, T> toStdMap() const;
@@ -640,13 +642,13 @@ Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::freeData(QMapData *x)
while (next != x) {
cur = next;
next = cur->forward[0];
-#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#if defined(_MSC_VER)
#pragma warning(disable:4189)
#endif
Node *concreteNode = concrete(reinterpret_cast<QMapData::Node *>(cur));
concreteNode->key.~Key();
concreteNode->value.~T();
-#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#if defined(_MSC_VER)
#pragma warning(default:4189)
#endif
}
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 36827d056b..a0df065227 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -4172,6 +4172,8 @@ int QRegExp::matchedLength() const
}
#ifndef QT_NO_REGEXP_CAPTURE
+
+#ifndef QT_NO_DEPRECATED
/*!
\obsolete
Returns the number of captures contained in the regular expression.
@@ -4182,6 +4184,7 @@ int QRegExp::numCaptures() const
{
return captureCount();
}
+#endif
/*!
\since 4.6
diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h
index e19c13080d..0b4a702c62 100644
--- a/src/corelib/tools/qregexp.h
+++ b/src/corelib/tools/qregexp.h
@@ -76,6 +76,10 @@ public:
QRegExp(const QRegExp &rx);
~QRegExp();
QRegExp &operator=(const QRegExp &rx);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QRegExp &operator=(QRegExp &&other)
+ { qSwap(priv,other.priv); return *this; }
+#endif
bool operator==(const QRegExp &rx) const;
inline bool operator!=(const QRegExp &rx) const { return !operator==(rx); }
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index bc76a3be45..40d3851f5d 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -54,7 +54,7 @@ struct QScopedPointerDeleter
static inline void cleanup(T *pointer)
{
// Enforce a complete type.
- // If you get a compile error here, read the secion on forward declared
+ // If you get a compile error here, read the section on forward declared
// classes in the QScopedPointer documentation.
typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
(void) sizeof(IsIncompleteType);
@@ -69,7 +69,7 @@ struct QScopedPointerArrayDeleter
static inline void cleanup(T *pointer)
{
// Enforce a complete type.
- // If you get a compile error here, read the secion on forward declared
+ // If you get a compile error here, read the section on forward declared
// classes in the QScopedPointer documentation.
typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
(void) sizeof(IsIncompleteType);
@@ -186,11 +186,18 @@ template <class T, class Cleanup>
Q_INLINE_TEMPLATE void qSwap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2)
{ p1.swap(p2); }
+namespace QtPrivate {
+ template <typename X, typename Y> struct QScopedArrayEnsureSameType;
+ template <typename X> struct QScopedArrayEnsureSameType<X,X> { typedef X* Type; };
+ template <typename X> struct QScopedArrayEnsureSameType<const X, X> { typedef X* Type; };
+}
+
template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
class QScopedArrayPointer : public QScopedPointer<T, Cleanup>
{
public:
- explicit inline QScopedArrayPointer(T *p = 0)
+ template <typename D>
+ explicit inline QScopedArrayPointer(D *p = 0, typename QtPrivate::QScopedArrayEnsureSameType<T,D>::Type = 0)
: QScopedPointer<T, Cleanup>(p)
{
}
@@ -206,6 +213,17 @@ public:
}
private:
+ explicit inline QScopedArrayPointer(void *) {
+ // Enforce the same type.
+
+ // If you get a compile error here, make sure you declare
+ // QScopedArrayPointer with the same template type as you pass to the
+ // constructor. See also the QScopedPointer documentation.
+
+ // Storing a scalar array as a pointer to a different type is not
+ // allowed and results in undefined behavior.
+ }
+
Q_DISABLE_COPY(QScopedArrayPointer)
};
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index fe50d4d5dd..dc3c45a046 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -61,6 +61,10 @@ public:
inline QSet<T> &operator=(const QSet<T> &other)
{ q_hash = other.q_hash; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSet<T> &operator=(QSet<T> &&other)
+ { qSwap(q_hash, other.q_hash); return *this; }
+#endif
inline bool operator==(const QSet<T> &other) const
{ return q_hash == other.q_hash; }
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 6483c90fa5..b646a9d3ce 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -113,6 +113,10 @@ public:
}
return *this;
}
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSharedDataPointer<T> &operator=(QSharedDataPointer<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline bool operator!() const { return !d; }
@@ -163,14 +167,12 @@ public:
explicit QExplicitlySharedDataPointer(T *data);
inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
-#ifndef QT_NO_MEMBER_TEMPLATES
template<class X>
inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) : d(static_cast<T *>(o.data()))
{
if(d)
d->ref.ref();
}
-#endif
inline QExplicitlySharedDataPointer<T> & operator=(const QExplicitlySharedDataPointer<T> &o) {
if (o.d != d) {
@@ -194,6 +196,10 @@ public:
}
return *this;
}
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSharedDataPointer<T> &operator=(QSharedDataPointer<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline bool operator!() const { return !d; }
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index 5fac9600c5..8f9559a96a 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -1275,8 +1275,6 @@ QT_END_NAMESPACE
-#if !defined(QT_NO_MEMBER_TEMPLATES)
-
//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
# ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
# if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
@@ -1501,5 +1499,3 @@ void QtSharedPointer::internalSafetyCheckCleanCheck()
}
QT_END_NAMESPACE
-
-#endif
diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h
index c51ade6598..e0f4dca1ec 100644
--- a/src/corelib/tools/qsharedpointer.h
+++ b/src/corelib/tools/qsharedpointer.h
@@ -47,10 +47,7 @@
#include <QtCore/qshareddata.h>
#ifndef Q_QDOC
-# if !defined(QT_NO_MEMBER_TEMPLATES)
-// QSharedPointer requires member template support
# include <QtCore/qsharedpointer_impl.h>
-# endif
#else
QT_BEGIN_HEADER
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 4cce33941b..20dda12ea3 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -109,7 +109,6 @@ namespace QtSharedPointer {
template <class T> inline void normalDeleter(T *t) { delete t; }
// this uses partial template specialization
- // the only compilers that didn't support this were MSVC 6.0 and 2002
template <class T> struct RemovePointer;
template <class T> struct RemovePointer<T *> { typedef T Type; };
template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; };
@@ -323,7 +322,6 @@ namespace QtSharedPointer {
protected:
typedef ExternalRefCountData Data;
- inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
inline void deref()
{ deref(d, this->value); }
static inline void deref(Data *d, T *value)
@@ -388,7 +386,13 @@ namespace QtSharedPointer {
template <class X>
inline void internalCopy(const ExternalRefCount<X> &other)
{
- internalSet(other.d, other.data());
+ Data *o = other.d;
+ T *actual = other.value;
+ if (o)
+ other.ref();
+ qSwap(d, o);
+ qSwap(this->value, actual);
+ deref(o, actual);
}
inline void internalSwap(ExternalRefCount &other)
@@ -404,6 +408,7 @@ namespace QtSharedPointer {
template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer);
template <class X, class Y> friend QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
#endif
+ inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
inline void internalSet(Data *o, T *actual)
{
@@ -460,6 +465,13 @@ public:
BaseClass::internalCopy(other);
return *this;
}
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSharedPointer<T> &operator=(QSharedPointer<T> &&other)
+ {
+ QSharedPointer<T>::internalSwap(other);
+ return *this;
+ }
+#endif
template <class X>
inline QSharedPointer(const QSharedPointer<X> &other) : BaseClass(other)
@@ -844,9 +856,13 @@ qobject_cast(const QWeakPointer<T> &src)
{
return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
}
-
#endif
+
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_MOVABLE_TYPE);
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_MOVABLE_TYPE);
+
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 3521b31850..7589f59efb 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -111,7 +111,23 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
int qFindStringBoyerMoore(const QChar *haystack, int haystackLen, int from,
const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
-
+static inline int qt_last_index_of(const QChar *haystack, int haystackLen, const QChar &needle,
+ int from, Qt::CaseSensitivity cs);
+static inline int qt_string_count(const QChar *haystack, int haystackLen,
+ const QChar *needle, int needleLen,
+ Qt::CaseSensitivity cs);
+static inline int qt_string_count(const QChar *haystack, int haystackLen,
+ const QChar &needle, Qt::CaseSensitivity cs);
+static inline int qt_find_latin1_string(const QChar *hay, int size, const QLatin1String &needle,
+ int from, Qt::CaseSensitivity cs);
+static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
+static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
+ const QLatin1String &needle, Qt::CaseSensitivity cs);
+static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
+static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
+ const QLatin1String &needle, Qt::CaseSensitivity cs);
// Unicode case-insensitive comparison
static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be)
@@ -350,11 +366,7 @@ inline char qToLower(char ch)
return ch;
}
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300
-const QString::Null QString::null;
-#else
const QString::Null QString::null = { };
-#endif
/*!
\macro QT_NO_CAST_FROM_ASCII
@@ -945,6 +957,24 @@ QString QString::fromWCharArray(const wchar_t *string, int size)
\sa utf16(), toAscii(), toLatin1(), toUtf8(), toLocal8Bit()
*/
+template<typename T> int toUcs4_helper(const unsigned short *uc, int length, T *out)
+{
+ int i = 0;
+ for (; i < length; ++i) {
+ uint u = uc[i];
+ if (QChar::isHighSurrogate(u) && i < length-1) {
+ ushort low = uc[i+1];
+ if (QChar::isLowSurrogate(low)) {
+ ++i;
+ u = QChar::surrogateToUcs4(u, low);
+ }
+ }
+ *out = T(u);
+ ++out;
+ }
+ return i;
+}
+
/*!
\since 4.2
@@ -969,21 +999,7 @@ int QString::toWCharArray(wchar_t *array) const
memcpy(array, utf16(), sizeof(wchar_t)*length());
return length();
} else {
- wchar_t *a = array;
- const unsigned short *uc = utf16();
- for (int i = 0; i < length(); ++i) {
- uint u = uc[i];
- if (QChar::isHighSurrogate(u) && i + 1 < length()) {
- ushort low = uc[i+1];
- if (QChar::isLowSurrogate(low)) {
- u = QChar::surrogateToUcs4(u, low);
- ++i;
- }
- }
- *a = wchar_t(u);
- ++a;
- }
- return a - array;
+ return toUcs4_helper<wchar_t>(utf16(), length(), array);
}
}
@@ -1316,7 +1332,9 @@ void QString::realloc(int alloc)
asciiCache->remove(d);
}
#endif
- d = static_cast<Data *>(q_check_ptr(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar))));
+ Data *p = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar)));
+ Q_CHECK_PTR(p);
+ d = p;
d->alloc = alloc;
d->data = d->array;
}
@@ -2480,14 +2498,10 @@ int QString::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
\sa lastIndexOf(), contains(), count()
*/
+
int QString::indexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) const
{
- int len = qstrlen(str.latin1());
- QVarLengthArray<ushort> s(len);
- for (int i = 0; i < len; ++i)
- s[i] = str.latin1()[i];
-
- return qFindString(unicode(), length(), from, (const QChar *)s.data(), len, cs);
+ return qt_find_latin1_string(unicode(), size(), str, from, cs);
}
int qFindString(
@@ -2577,6 +2591,23 @@ int QString::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
return findChar(unicode(), length(), ch, from, cs);
}
+/*!
+ \since 4.8
+
+ \overload indexOf()
+
+ Returns the index position of the first occurrence of the string
+ reference \a str in this string, searching forward from index
+ position \a from. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+*/
+int QString::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
+{
+ return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
+}
+
static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *needle, int sl, Qt::CaseSensitivity cs)
{
/*
@@ -2656,12 +2687,13 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
if (from > delta)
from = delta;
-
return lastIndexOfHelper(d->data, from, str.d->data, str.d->size, cs);
}
/*!
\since 4.5
+ \overload lastIndexOf()
+
Returns the index position of the last occurrence of the string \a
str in this string, searching backward from index position \a
from. If \a from is -1 (default), the search starts at the last
@@ -2709,26 +2741,43 @@ int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity
*/
int QString::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- ushort c = ch.unicode();
- if (from < 0)
- from += d->size;
- if (from < 0 || from >= d->size)
- return -1;
- if (from >= 0) {
- const ushort *n = d->data + from;
- const ushort *b = d->data;
- if (cs == Qt::CaseSensitive) {
- for (; n >= b; --n)
- if (*n == c)
- return n - b;
- } else {
- c = foldCase(c);
- for (; n >= b; --n)
- if (foldCase(*n) == c)
- return n - b;
- }
+ return qt_last_index_of(unicode(), size(), ch, from, cs);
}
+
+/*!
+ \since 4.8
+ \overload lastIndexOf()
+
+ Returns the index position of the last occurrence of the string
+ reference \a str in this string, searching backward from index
+ position \a from. If \a from is -1 (default), the search starts at
+ the last character; if \a from is -2, at the next to last character
+ and so on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), contains(), count()
+*/
+int QString::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
+{
+ const int sl = str.size();
+ if (sl == 1)
+ return lastIndexOf(str.at(0), from, cs);
+
+ const int l = d->size;
+ if (from < 0)
+ from += l;
+ int delta = l - sl;
+ if (from == l && sl == 0)
+ return from;
+ if (from < 0 || from >= l || delta < 0)
return -1;
+ if (from > delta)
+ from = delta;
+
+ return lastIndexOfHelper(d->data, from, reinterpret_cast<const ushort*>(str.unicode()),
+ str.size(), cs);
}
#ifndef QT_NO_REGEXP
@@ -2903,19 +2952,10 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
\sa contains(), indexOf()
*/
+
int QString::count(const QString &str, Qt::CaseSensitivity cs) const
{
- int num = 0;
- int i = -1;
- if (d->size > 500 && str.d->size > 5) {
- QStringMatcher matcher(str, cs);
- while ((i = matcher.indexIn(*this, i + 1)) != -1)
- ++num;
- } else {
- while ((i = indexOf(str, i + 1, cs)) != -1)
- ++num;
- }
- return num;
+ return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
}
/*!
@@ -2923,25 +2963,29 @@ int QString::count(const QString &str, Qt::CaseSensitivity cs) const
Returns the number of occurrences of character \a ch in the string.
*/
+
int QString::count(QChar ch, Qt::CaseSensitivity cs) const
{
- ushort c = ch.unicode();
- int num = 0;
- const ushort *i = d->data + d->size;
- const ushort *b = d->data;
- if (cs == Qt::CaseSensitive) {
- while (i != b)
- if (*--i == c)
- ++num;
- } else {
- c = foldCase(c);
- while (i != b)
- if (foldCase(*(--i)) == c)
- ++num;
+ return qt_string_count(unicode(), size(), ch, cs);
}
- return num;
+
+/*!
+ \since 4.8
+ \overload count()
+ Returns the number of (potentially overlapping) occurrences of the
+ string reference \a str in this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa contains(), indexOf()
+*/
+int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
+{
+ return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
}
+
/*! \fn bool QString::contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
Returns true if this string contains an occurrence of the string
@@ -2964,6 +3008,18 @@ int QString::count(QChar ch, Qt::CaseSensitivity cs) const
character \a ch; otherwise returns false.
*/
+/*! \fn bool QString::contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 4.8
+
+ Returns true if this string contains an occurrence of the string
+ reference \a str; otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), count()
+*/
+
/*! \fn bool QString::contains(const QRegExp &rx) const
\overload contains()
@@ -3365,22 +3421,8 @@ QString QString::mid(int position, int n) const
*/
bool QString::startsWith(const QString& s, Qt::CaseSensitivity cs) const
{
- if (d == &shared_null)
- return (s.d == &shared_null);
- if (d->size == 0)
- return s.d->size == 0;
- if (s.d->size > d->size)
- return false;
- if (cs == Qt::CaseSensitive) {
- return qMemEquals(d->data, s.d->data, s.d->size);
- } else {
- uint last = 0;
- uint olast = 0;
- for (int i = 0; i < s.d->size; ++i)
- if (foldCase(d->data[i], last) != foldCase(s.d->data[i], olast))
- return false;
- }
- return true;
+ return qt_starts_with(isNull() ? 0 : unicode(), size(),
+ s.isNull() ? 0 : s.unicode(), s.size(), cs);
}
/*!
@@ -3388,24 +3430,7 @@ bool QString::startsWith(const QString& s, Qt::CaseSensitivity cs) const
*/
bool QString::startsWith(const QLatin1String& s, Qt::CaseSensitivity cs) const
{
- if (d == &shared_null)
- return (s.latin1() == 0);
- if (d->size == 0)
- return !s.latin1() || *s.latin1() == 0;
- int slen = qstrlen(s.latin1());
- if (slen > d->size)
- return false;
- const uchar *latin = (const uchar *)s.latin1();
- if (cs == Qt::CaseSensitive) {
- for (int i = 0; i < slen; ++i)
- if (d->data[i] != latin[i])
- return false;
- } else {
- for (int i = 0; i < slen; ++i)
- if (foldCase(d->data[i]) != foldCase((ushort)latin[i]))
- return false;
- }
- return true;
+ return qt_starts_with(isNull() ? 0 : unicode(), size(), s, cs);
}
/*!
@@ -3423,6 +3448,23 @@ bool QString::startsWith(const QChar &c, Qt::CaseSensitivity cs) const
}
/*!
+ \since 4.8
+ \overload
+ Returns true if the string starts with the string reference \a s;
+ otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa endsWith()
+*/
+bool QString::startsWith(const QStringRef &s, Qt::CaseSensitivity cs) const
+{
+ return qt_starts_with(isNull() ? 0 : unicode(), size(),
+ s.isNull() ? 0 : s.unicode(), s.size(), cs);
+}
+
+/*!
Returns true if the string ends with \a s; otherwise returns
false.
@@ -3435,49 +3477,34 @@ bool QString::startsWith(const QChar &c, Qt::CaseSensitivity cs) const
*/
bool QString::endsWith(const QString& s, Qt::CaseSensitivity cs) const
{
- if (d == &shared_null)
- return (s.d == &shared_null);
- if (d->size == 0)
- return s.d->size == 0;
- int pos = d->size - s.d->size;
- if (pos < 0)
- return false;
- if (cs == Qt::CaseSensitive) {
- return qMemEquals(d->data + pos, s.d->data, s.d->size);
- } else {
- uint last = 0;
- uint olast = 0;
- for (int i = 0; i < s.length(); i++)
- if (foldCase(d->data[pos+i], last) != foldCase(s.d->data[i], olast))
- return false;
+ return qt_ends_with(isNull() ? 0 : unicode(), size(),
+ s.isNull() ? 0 : s.unicode(), s.size(), cs);
}
- return true;
+
+/*!
+ \since 4.8
+ \overload endsWith()
+ Returns true if the string ends with the string reference \a s;
+ otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa startsWith()
+*/
+bool QString::endsWith(const QStringRef &s, Qt::CaseSensitivity cs) const
+{
+ return qt_ends_with(isNull() ? 0 : unicode(), size(),
+ s.isNull() ? 0 : s.unicode(), s.size(), cs);
}
+
/*!
\overload endsWith()
*/
bool QString::endsWith(const QLatin1String& s, Qt::CaseSensitivity cs) const
{
- if (d == &shared_null)
- return (s.latin1() == 0);
- if (d->size == 0)
- return !s.latin1() || *s.latin1() == 0;
- int slen = qstrlen(s.latin1());
- int pos = d->size - slen;
- const uchar *latin = (const uchar *)s.latin1();
- if (pos < 0)
- return false;
- if (cs == Qt::CaseSensitive) {
- for (int i = 0; i < slen; i++)
- if (d->data[pos+i] != latin[i])
- return false;
- } else {
- for (int i = 0; i < slen; i++)
- if (foldCase(d->data[pos+i]) != foldCase((ushort)latin[i]))
- return false;
- }
- return true;
+ return qt_ends_with(isNull() ? 0 : unicode(), size(), s, cs);
}
/*!
@@ -3716,20 +3743,8 @@ QVector<uint> QString::toUcs4() const
{
QVector<uint> v(length());
uint *a = v.data();
- const unsigned short *uc = utf16();
- for (int i = 0; i < length(); ++i) {
- uint u = uc[i];
- if (QChar(u).isHighSurrogate() && i < length()-1) {
- ushort low = uc[i+1];
- if (QChar(low).isLowSurrogate()) {
- ++i;
- u = QChar::surrogateToUcs4(u, low);
- }
- }
- *a = u;
- ++a;
- }
- v.resize(a - v.data());
+ int len = toUcs4_helper<uint>(utf16(), length(), a);
+ v.resize(len);
return v;
}
@@ -7659,6 +7674,7 @@ QDataStream &operator>>(QDataStream &in, QString &str)
Use the startsWith(QString, Qt::CaseSensitive) overload instead.
*/
+
/*!
\fn bool QString::endsWith(const QString &s, bool cs) const
@@ -8364,4 +8380,717 @@ QStringRef QString::midRef(int position, int n) const
return QStringRef(this, position, n);
}
+/*!
+ \since 4.8
+
+ Returns the index position of the first occurrence of the string \a
+ str in this string reference, searching forward from index position
+ \a from. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ If \a from is -1, the search starts at the last character; if it is
+ -2, at the next to last character and so on.
+
+ \sa QString::indexOf(), lastIndexOf(), contains(), count()
+*/
+int QStringRef::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
+{
+ return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
+}
+
+/*!
+ \since 4.8
+ \overload indexOf()
+
+ Returns the index position of the first occurrence of the
+ character \a ch in the string reference, searching forward from
+ index position \a from. Returns -1 if \a ch could not be found.
+
+ \sa QString::indexOf(), lastIndexOf(), contains(), count()
+*/
+int QStringRef::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
+{
+ return findChar(unicode(), length(), ch, from, cs);
+}
+
+/*!
+ \since 4.8
+
+ Returns the index position of the first occurrence of the string \a
+ str in this string reference, searching forward from index position
+ \a from. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ If \a from is -1, the search starts at the last character; if it is
+ -2, at the next to last character and so on.
+
+ \sa QString::indexOf(), lastIndexOf(), contains(), count()
+*/
+int QStringRef::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
+{
+ return qt_find_latin1_string(unicode(), size(), str, from, cs);
+}
+
+/*!
+ \since 4.8
+
+ \overload indexOf()
+
+ Returns the index position of the first occurrence of the string
+ reference \a str in this string reference, searching forward from
+ index position \a from. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::indexOf(), lastIndexOf(), contains(), count()
+*/
+int QStringRef::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
+{
+ return qFindString(unicode(), size(), from, str.unicode(), str.size(), cs);
+}
+
+/*!
+ \since 4.8
+
+ Returns the index position of the last occurrence of the string \a
+ str in this string reference, searching backward from index position
+ \a from. If \a from is -1 (default), the search starts at the last
+ character; if \a from is -2, at the next to last character and so
+ on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::lastIndexOf(), indexOf(), contains(), count()
+*/
+int QStringRef::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
+{
+ const int sl = str.size();
+ if (sl == 1)
+ return lastIndexOf(str.at(0), from, cs);
+
+ const int l = size();;
+ if (from < 0)
+ from += l;
+ int delta = l - sl;
+ if (from == l && sl == 0)
+ return from;
+ if (from < 0 || from >= l || delta < 0)
+ return -1;
+ if (from > delta)
+ from = delta;
+
+ return lastIndexOfHelper(reinterpret_cast<const ushort*>(unicode()), from,
+ reinterpret_cast<const ushort*>(str.unicode()), str.size(), cs);
+}
+
+/*!
+ \since 4.8
+ \overload lastIndexOf()
+
+ Returns the index position of the last occurrence of the character
+ \a ch, searching backward from position \a from.
+
+ \sa QString::lastIndexOf(), indexOf(), contains(), count()
+*/
+int QStringRef::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
+{
+ return qt_last_index_of(unicode(), size(), ch, from, cs);
+}
+
+/*!
+ \since 4.8
+ \overload lastIndexOf()
+
+ Returns the index position of the last occurrence of the string \a
+ str in this string reference, searching backward from index position
+ \a from. If \a from is -1 (default), the search starts at the last
+ character; if \a from is -2, at the next to last character and so
+ on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::lastIndexOf(), indexOf(), contains(), count()
+*/
+int QStringRef::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
+{
+ const int sl = qstrlen(str.latin1());
+ if (sl == 1)
+ return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
+
+ const int l = size();
+ if (from < 0)
+ from += l;
+ int delta = l - sl;
+ if (from == l && sl == 0)
+ return from;
+ if (from < 0 || from >= l || delta < 0)
+ return -1;
+ if (from > delta)
+ from = delta;
+
+ QVarLengthArray<ushort> s(sl);
+ for (int i = 0; i < sl; ++i)
+ s[i] = str.latin1()[i];
+
+ return lastIndexOfHelper(reinterpret_cast<const ushort*>(unicode()), from, s.data(), sl, cs);
+}
+
+/*!
+ \since 4.8
+ \overload lastIndexOf()
+
+ Returns the index position of the last occurrence of the string
+ reference \a str in this string reference, searching backward from
+ index position \a from. If \a from is -1 (default), the search
+ starts at the last character; if \a from is -2, at the next to last
+ character and so on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::lastIndexOf(), indexOf(), contains(), count()
+*/
+int QStringRef::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
+{
+ const int sl = str.size();
+ if (sl == 1)
+ return lastIndexOf(str.at(0), from, cs);
+
+ const int l = size();
+ if (from < 0)
+ from += l;
+ int delta = l - sl;
+ if (from == l && sl == 0)
+ return from;
+ if (from < 0 || from >= l || delta < 0)
+ return -1;
+ if (from > delta)
+ from = delta;
+
+ return lastIndexOfHelper(reinterpret_cast<const ushort*>(unicode()), from,
+ reinterpret_cast<const ushort*>(str.unicode()),
+ str.size(), cs);
+}
+
+/*!
+ \since 4.8
+ Returns the number of (potentially overlapping) occurrences of
+ the string \a str in this string reference.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa QString::count(), contains(), indexOf()
+*/
+int QStringRef::count(const QString &str, Qt::CaseSensitivity cs) const
+{
+ return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
+}
+
+/*!
+ \since 4.8
+ \overload count()
+
+ Returns the number of occurrences of the character \a ch in the
+ string reference.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa QString::count(), contains(), indexOf()
+*/
+int QStringRef::count(QChar ch, Qt::CaseSensitivity cs) const
+{
+ return qt_string_count(unicode(), size(), ch, cs);
+}
+
+/*!
+ \since 4.8
+ \overload count()
+
+ Returns the number of (potentially overlapping) occurrences of the
+ string reference \a str in this string reference.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa QString::count(), contains(), indexOf()
+*/
+int QStringRef::count(const QStringRef &str, Qt::CaseSensitivity cs) const
+{
+ return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
+}
+
+/*!
+ \since 4.8
+
+ Returns true if the string reference starts with \a str; otherwise
+ returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa QString::startsWith(), endsWith()
+*/
+bool QStringRef::startsWith(const QString &str, Qt::CaseSensitivity cs) const
+{
+ return qt_starts_with(isNull() ? 0 : unicode(), size(),
+ str.isNull() ? 0 : str.unicode(), str.size(), cs);
+}
+
+/*!
+ \since 4.8
+ \overload startsWith()
+ \sa QString::startsWith(), endsWith()
+*/
+bool QStringRef::startsWith(QLatin1String str, Qt::CaseSensitivity cs) const
+{
+ return qt_starts_with(isNull() ? 0 : unicode(), size(), str, cs);
+}
+
+/*!
+ \since 4.8
+ \overload startsWith()
+ \sa QString::startsWith(), endsWith()
+*/
+bool QStringRef::startsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
+{
+ return qt_starts_with(isNull() ? 0 : unicode(), size(),
+ str.isNull() ? 0 : str.unicode(), str.size(), cs);
+}
+
+/*!
+ \since 4.8
+ \overload startsWith()
+
+ Returns true if the string reference starts with \a ch; otherwise
+ returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::startsWith(), endsWith()
+*/
+bool QStringRef::startsWith(QChar ch, Qt::CaseSensitivity cs) const
+{
+ if (!isEmpty()) {
+ const ushort *data = reinterpret_cast<const ushort*>(unicode());
+ return (cs == Qt::CaseSensitive
+ ? data[0] == ch
+ : foldCase(data[0]) == foldCase(ch.unicode()));
+ } else {
+ return false;
+ }
+}
+
+/*!
+ \since 4.8
+ Returns true if the string reference ends with \a str; otherwise
+ returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::endsWith(), startsWith()
+*/
+bool QStringRef::endsWith(const QString &str, Qt::CaseSensitivity cs) const
+{
+ return qt_ends_with(isNull() ? 0 : unicode(), size(),
+ str.isNull() ? 0 : str.unicode(), str.size(), cs);
+}
+
+/*!
+ \since 4.8
+ \overload endsWith()
+
+ Returns true if the string reference ends with \a ch; otherwise
+ returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::endsWith(), endsWith()
+*/
+bool QStringRef::endsWith(QChar ch, Qt::CaseSensitivity cs) const
+{
+ if (!isEmpty()) {
+ const ushort *data = reinterpret_cast<const ushort*>(unicode());
+ const int size = length();
+ return (cs == Qt::CaseSensitive
+ ? data[size - 1] == ch
+ : foldCase(data[size - 1]) == foldCase(ch.unicode()));
+ } else {
+ return false;
+ }
+}
+
+/*!
+ \since 4.8
+ \overload endsWith()
+ \sa QString::endsWith(), endsWith()
+*/
+bool QStringRef::endsWith(QLatin1String str, Qt::CaseSensitivity cs) const
+{
+ return qt_ends_with(isNull() ? 0 : unicode(), size(), str, cs);
+}
+
+/*!
+ \since 4.8
+ \overload endsWith()
+ \sa QString::endsWith(), endsWith()
+*/
+bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
+{
+ return qt_ends_with(isNull() ? 0 : unicode(), size(),
+ str.isNull() ? 0 : str.unicode(), str.size(), cs);
+}
+
+
+/*! \fn bool QStringRef::contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+
+ \since 4.8
+ Returns true if this string reference contains an occurrence of
+ the string \a str; otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), count()
+*/
+
+/*! \fn bool QStringRef::contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+
+ \overload contains()
+ \since 4.8
+
+ Returns true if this string contains an occurrence of the
+ character \a ch; otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+*/
+
+/*! \fn bool QStringRef::contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \overload contains()
+ \since 4.8
+
+ Returns true if this string reference contains an occurrence of
+ the string reference \a str; otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), count()
+*/
+
+/*! \fn bool QStringRef::contains(QLatin1String str, Qt::CaseSensitivity cs) const
+ \since 4,8
+ \overload contains()
+
+ Returns true if this string reference contains an occurrence of
+ the string \a str; otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), count()
+*/
+
+static inline int qt_last_index_of(const QChar *haystack, int haystackLen, const QChar &needle,
+ int from, Qt::CaseSensitivity cs)
+{
+ ushort c = needle.unicode();
+ if (from < 0)
+ from += haystackLen;
+ if (from < 0 || from >= haystackLen)
+ return -1;
+ if (from >= 0) {
+ const ushort *b = reinterpret_cast<const ushort*>(haystack);
+ const ushort *n = b + from;
+ if (cs == Qt::CaseSensitive) {
+ for (; n >= b; --n)
+ if (*n == c)
+ return n - b;
+ } else {
+ c = foldCase(c);
+ for (; n >= b; --n)
+ if (foldCase(*n) == c)
+ return n - b;
+ }
+ }
+ return -1;
+
+
+}
+
+static inline int qt_string_count(const QChar *haystack, int haystackLen,
+ const QChar *needle, int needleLen,
+ Qt::CaseSensitivity cs)
+{
+ int num = 0;
+ int i = -1;
+ if (haystackLen > 500 && needleLen > 5) {
+ QStringMatcher matcher(needle, needleLen, cs);
+ while ((i = matcher.indexIn(haystack, haystackLen, i + 1)) != -1)
+ ++num;
+ } else {
+ while ((i = qFindString(haystack, haystackLen, i + 1, needle, needleLen, cs)) != -1)
+ ++num;
+ }
+ return num;
+}
+
+static inline int qt_string_count(const QChar *unicode, int size, const QChar &ch,
+ Qt::CaseSensitivity cs)
+{
+ ushort c = ch.unicode();
+ int num = 0;
+ const ushort *b = reinterpret_cast<const ushort*>(unicode);
+ const ushort *i = b + size;
+ if (cs == Qt::CaseSensitive) {
+ while (i != b)
+ if (*--i == c)
+ ++num;
+ } else {
+ c = foldCase(c);
+ while (i != b)
+ if (foldCase(*(--i)) == c)
+ ++num;
+ }
+ return num;
+}
+
+static inline int qt_find_latin1_string(const QChar *haystack, int size,
+ const QLatin1String &needle,
+ int from, Qt::CaseSensitivity cs)
+{
+ const char *latin1 = needle.latin1();
+ int len = qstrlen(latin1);
+ QVarLengthArray<ushort> s(len);
+ for (int i = 0; i < len; ++i)
+ s[i] = latin1[i];
+
+ return qFindString(haystack, size, from,
+ reinterpret_cast<const QChar*>(s.constData()), len, cs);
+}
+
+static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
+{
+ if (!haystack)
+ return !needle;
+ if (haystackLen == 0)
+ return needleLen == 0;
+ if (needleLen > haystackLen)
+ return false;
+
+ const ushort *h = reinterpret_cast<const ushort*>(haystack);
+ const ushort *n = reinterpret_cast<const ushort*>(needle);
+
+ if (cs == Qt::CaseSensitive) {
+ return qMemEquals(h, n, needleLen);
+ } else {
+ uint last = 0;
+ uint olast = 0;
+ for (int i = 0; i < needleLen; ++i)
+ if (foldCase(h[i], last) != foldCase(n[i], olast))
+ return false;
+ }
+ return true;
+}
+
+static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
+ const QLatin1String &needle, Qt::CaseSensitivity cs)
+{
+ if (!haystack)
+ return !needle.latin1();
+ if (haystackLen == 0)
+ return !needle.latin1() || *needle.latin1() == 0;
+ const int slen = qstrlen(needle.latin1());
+ if (slen > haystackLen)
+ return false;
+ const ushort *data = reinterpret_cast<const ushort*>(haystack);
+ const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
+ if (cs == Qt::CaseSensitive) {
+ for (int i = 0; i < slen; ++i)
+ if (data[i] != latin[i])
+ return false;
+ } else {
+ for (int i = 0; i < slen; ++i)
+ if (foldCase(data[i]) != foldCase((ushort)latin[i]))
+ return false;
+ }
+ return true;
+}
+
+static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
+{
+ if (!haystack)
+ return !needle;
+ if (haystackLen == 0)
+ return needleLen == 0;
+ const int pos = haystackLen - needleLen;
+ if (pos < 0)
+ return false;
+
+ const ushort *h = reinterpret_cast<const ushort*>(haystack);
+ const ushort *n = reinterpret_cast<const ushort*>(needle);
+
+ if (cs == Qt::CaseSensitive) {
+ return qMemEquals(h + pos, n, needleLen);
+ } else {
+ uint last = 0;
+ uint olast = 0;
+ for (int i = 0; i < needleLen; i++)
+ if (foldCase(h[pos+i], last) != foldCase(n[i], olast))
+ return false;
+ }
+ return true;
+}
+
+
+static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
+ const QLatin1String &needle, Qt::CaseSensitivity cs)
+{
+ if (!haystack)
+ return !needle.latin1();
+ if (haystackLen == 0)
+ return !needle.latin1() || *needle.latin1() == 0;
+ const int slen = qstrlen(needle.latin1());
+ int pos = haystackLen - slen;
+ if (pos < 0)
+ return false;
+ const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
+ const ushort *data = reinterpret_cast<const ushort*>(haystack);
+ if (cs == Qt::CaseSensitive) {
+ for (int i = 0; i < slen; i++)
+ if (data[pos+i] != latin[i])
+ return false;
+ } else {
+ for (int i = 0; i < slen; i++)
+ if (foldCase(data[pos+i]) != foldCase((ushort)latin[i]))
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \since 4.8
+
+ Returns a Latin-1 representation of the string as a QByteArray.
+
+ The returned byte array is undefined if the string contains non-Latin1
+ characters. Those characters may be suppressed or replaced with a
+ question mark.
+
+ \sa toAscii(), toUtf8(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QStringRef::toLatin1() const
+{
+ return toLatin1_helper(unicode(), length());
+}
+
+/*!
+ \since 4.8
+
+ Returns an 8-bit representation of the string as a QByteArray.
+
+ If a codec has been set using QTextCodec::setCodecForCStrings(),
+ it is used to convert Unicode to 8-bit char; otherwise this
+ function does the same as toLatin1().
+
+ Note that, despite the name, this function does not necessarily return an US-ASCII
+ (ANSI X3.4-1986) string and its result may not be US-ASCII compatible.
+
+ \sa toLatin1(), toUtf8(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QStringRef::toAscii() const
+{
+#ifndef QT_NO_TEXTCODEC
+ if (QString::codecForCStrings)
+ return QString::codecForCStrings->fromUnicode(unicode(), length());
+#endif // QT_NO_TEXTCODEC
+ return toLatin1();
+}
+
+/*!
+ \since 4.8
+
+ Returns the local 8-bit representation of the string as a
+ QByteArray. The returned byte array is undefined if the string
+ contains characters not supported by the local 8-bit encoding.
+
+ QTextCodec::codecForLocale() is used to perform the conversion from
+ Unicode. If the locale encoding could not be determined, this function
+ does the same as toLatin1().
+
+ If this string contains any characters that cannot be encoded in the
+ locale, the returned byte array is undefined. Those characters may be
+ suppressed or replaced by another.
+
+ \sa toAscii(), toLatin1(), toUtf8(), QTextCodec
+*/
+QByteArray QStringRef::toLocal8Bit() const
+{
+#ifndef QT_NO_TEXTCODEC
+ if (QTextCodec::codecForLocale())
+ return QTextCodec::codecForLocale()->fromUnicode(unicode(), length());
+#endif // QT_NO_TEXTCODEC
+ return toLatin1();
+}
+
+/*!
+ \since 4.8
+
+ Returns a UTF-8 representation of the string as a QByteArray.
+
+ UTF-8 is a Unicode codec and can represent all characters in a Unicode
+ string like QString.
+
+ However, in the Unicode range, there are certain codepoints that are not
+ considered characters. The Unicode standard reserves the last two
+ codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF,
+ U+2FFFE, etc.), as well as 16 codepoints in the range U+FDD0..U+FDDF,
+ inclusive, as non-characters. If any of those appear in the string, they
+ may be discarded and will not appear in the UTF-8 representation, or they
+ may be replaced by one or more replacement characters.
+
+ \sa toAscii(), toLatin1(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QStringRef::toUtf8() const
+{
+ if (isNull())
+ return QByteArray();
+
+ return QUtf8::convertFromUnicode(constData(), length(), 0);
+}
+
+/*!
+ \since 4.8
+
+ Returns a UCS-4/UTF-32 representation of the string as a QVector<uint>.
+
+ UCS-4 is a Unicode codec and is lossless. All characters from this string
+ can be encoded in UCS-4.
+
+ \sa fromUtf8(), toAscii(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray()
+*/
+QVector<uint> QStringRef::toUcs4() const
+{
+ QVector<uint> v(length());
+ uint *a = v.data();
+ int len = toUcs4_helper<uint>(reinterpret_cast<const unsigned short *>(unicode()), length(), a);
+ v.resize(len);
+ return v;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 06e4d47408..589fdc2d20 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -51,14 +51,7 @@
#endif
#ifndef QT_NO_STL
-# if defined (Q_CC_MSVC_NET) && _MSC_VER < 1310 // Avoids nasty warning for xlocale, line 450
-# pragma warning (push)
-# pragma warning (disable : 4189)
-# include <string>
-# pragma warning (pop)
-# else
-# include <string>
-# endif
+# include <string>
# ifndef QT_NO_STL_WCHAR
// workaround for some headers not typedef'ing std::wstring
@@ -111,7 +104,10 @@ public:
QString &operator=(QChar c);
QString &operator=(const QString &);
inline QString &operator=(const QLatin1String &);
-
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QString &operator=(QString &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline int size() const { return d->size; }
inline int count() const { return d->size; }
inline int length() const;
@@ -198,14 +194,18 @@ public:
int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int indexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int indexOf(const QLatin1String &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int indexOf(const QStringRef &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(QChar c, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(const QString &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(const QLatin1String &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(const QStringRef &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline QBool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline QBool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline QBool contains(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#ifndef QT_NO_REGEXP
int indexOf(const QRegExp &, int from = 0) const;
@@ -241,9 +241,11 @@ public:
QStringRef midRef(int position, int n = -1) const Q_REQUIRED_RESULT;
bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool startsWith(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(const QLatin1String &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(const QChar &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool endsWith(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith(const QLatin1String &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith(const QChar &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@@ -902,6 +904,8 @@ inline QString::const_iterator QString::constEnd() const
{ return reinterpret_cast<const QChar*>(d->data + d->size); }
inline QBool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return QBool(indexOf(s, 0, cs) != -1); }
+inline QBool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
+{ return QBool(indexOf(s, 0, cs) != -1); }
inline QBool QString::contains(QChar c, Qt::CaseSensitivity cs) const
{ return QBool(indexOf(c, 0, cs) != -1); }
@@ -1123,6 +1127,34 @@ public:
m_size = other.m_size; return *this;
}
+ int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int indexOf(QLatin1String str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int indexOf(const QStringRef &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(const QString &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(QChar ch, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(QLatin1String str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ inline QBool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline QBool contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline QBool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline QBool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool startsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool endsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
inline QStringRef &operator=(const QString *string);
inline const QChar *unicode() const {
@@ -1133,6 +1165,12 @@ public:
inline const QChar *data() const { return unicode(); }
inline const QChar *constData() const { return unicode(); }
+ QByteArray toAscii() const Q_REQUIRED_RESULT;
+ QByteArray toLatin1() const Q_REQUIRED_RESULT;
+ QByteArray toUtf8() const Q_REQUIRED_RESULT;
+ QByteArray toLocal8Bit() const Q_REQUIRED_RESULT;
+ QVector<uint> toUcs4() const Q_REQUIRED_RESULT;
+
inline void clear() { m_string = 0; m_position = m_size = 0; }
QString toString() const;
inline bool isEmpty() const { return m_size == 0; }
@@ -1241,6 +1279,16 @@ inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QString &s
inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef &s2)
{ return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
+inline QBool QStringRef::contains(const QString &s, Qt::CaseSensitivity cs) const
+{ return QBool(indexOf(s, 0, cs) != -1); }
+inline QBool QStringRef::contains(QLatin1String s, Qt::CaseSensitivity cs) const
+{ return QBool(indexOf(s, 0, cs) != -1); }
+inline QBool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const
+{ return QBool(indexOf(c, 0, cs) != -1); }
+inline QBool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
+{ return QBool(indexOf(s, 0, cs) != -1); }
+
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 2b8d054ca4..7eee33dc76 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -53,6 +53,9 @@
#endif
#include <stdlib.h>
#include <string.h>
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+#include <initializer_list>
+#endif
QT_BEGIN_HEADER
@@ -118,6 +121,13 @@ public:
inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
inline ~QVector() { if (!d) return; if (!d->ref.deref()) free(p); }
QVector<T> &operator=(const QVector<T> &v);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QVector<T> operator=(QVector<T> &&other)
+ { qSwap(p, other.p); return *this; }
+#endif
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ inline QVector(std::initializer_list<T> args);
+#endif
bool operator==(const QVector<T> &v) const;
inline bool operator!=(const QVector<T> &v) const { return !(*this == v); }
@@ -297,7 +307,6 @@ public:
inline std::vector<T> toStdVector() const
{ std::vector<T> tmp; tmp.reserve(size()); qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
#endif
-
private:
friend class QRegion; // Optimization for QRegion::rects()
@@ -426,6 +435,22 @@ QVector<T>::QVector(int asize, const T &t)
new (--i) T(t);
}
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+template <typename T>
+QVector<T>::QVector(std::initializer_list<T> args)
+{
+ p = malloc(args.size());
+ d->ref = 1;
+ d->alloc = d->size = args.size();
+ d->sharable = true;
+ d->capacity = false;
+ T* i = p->array + d->size;
+ auto it = args.end();
+ while (i != p->array)
+ new (--i) T(*(--it));
+}
+#endif
+
template <typename T>
void QVector<T>::free(Data *x)
{
@@ -790,11 +815,8 @@ QT_END_INCLUDE_NAMESPACE
#else
#define Q_TEMPLATE_EXTERN extern
#endif
-# pragma warning(push) /* MSVC 6.0 doesn't care about the disabling in qglobal.h (why?), so do it here */
-# pragma warning(disable: 4231) /* nonstandard extension used : 'extern' before template explicit instantiation */
Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPointF>;
Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPoint>;
-# pragma warning(pop)
#endif
QT_END_NAMESPACE
diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp
index 4e9c1adc7a..9ff0ff154d 100644
--- a/src/dbus/qdbusabstractinterface.cpp
+++ b/src/dbus/qdbusabstractinterface.cpp
@@ -208,7 +208,7 @@ bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q
QLatin1String(DBUS_INTERFACE_PROPERTIES),
QLatin1String("Set"));
QDBusMessagePrivate::setParametersValidated(msg, true);
- msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value));
+ msg << interface << QString::fromUtf8(mp.name()) << QVariant::fromValue(QDBusVariant(value));
QDBusMessage reply = connection.call(msg, QDBus::Block);
if (reply.type() != QDBusMessage::ReplyMessage) {
diff --git a/src/dbus/qdbusdemarshaller.cpp b/src/dbus/qdbusdemarshaller.cpp
index 6e19218cca..0df4c6bf57 100644
--- a/src/dbus/qdbusdemarshaller.cpp
+++ b/src/dbus/qdbusdemarshaller.cpp
@@ -188,11 +188,11 @@ QVariant QDBusDemarshaller::toVariantInternal()
{
switch (q_dbus_message_iter_get_arg_type(&iterator)) {
case DBUS_TYPE_BYTE:
- return qVariantFromValue(toByte());
+ return QVariant::fromValue(toByte());
case DBUS_TYPE_INT16:
- return qVariantFromValue(toShort());
+ return QVariant::fromValue(toShort());
case DBUS_TYPE_UINT16:
- return qVariantFromValue(toUShort());
+ return QVariant::fromValue(toUShort());
case DBUS_TYPE_INT32:
return toInt();
case DBUS_TYPE_UINT32:
@@ -208,11 +208,11 @@ QVariant QDBusDemarshaller::toVariantInternal()
case DBUS_TYPE_STRING:
return toString();
case DBUS_TYPE_OBJECT_PATH:
- return qVariantFromValue(toObjectPath());
+ return QVariant::fromValue(toObjectPath());
case DBUS_TYPE_SIGNATURE:
- return qVariantFromValue(toSignature());
+ return QVariant::fromValue(toSignature());
case DBUS_TYPE_VARIANT:
- return qVariantFromValue(toVariant());
+ return QVariant::fromValue(toVariant());
case DBUS_TYPE_ARRAY:
switch (q_dbus_message_iter_get_element_type(&iterator)) {
@@ -222,14 +222,14 @@ QVariant QDBusDemarshaller::toVariantInternal()
case DBUS_TYPE_STRING:
return toStringList();
case DBUS_TYPE_DICT_ENTRY:
- return qVariantFromValue(duplicate());
+ return QVariant::fromValue(duplicate());
default:
- return qVariantFromValue(duplicate());
+ return QVariant::fromValue(duplicate());
}
case DBUS_TYPE_STRUCT:
- return qVariantFromValue(duplicate());
+ return QVariant::fromValue(duplicate());
default:
qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 3833874aaf..498c1cbcb4 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -809,14 +809,14 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu
slotData.slotIdx = -1;
slotData.metaTypes.clear();
slotCache.hash.insert(cacheKey, slotData);
- object->setProperty(cachePropertyName, qVariantFromValue(slotCache));
+ object->setProperty(cachePropertyName, QVariant::fromValue(slotCache));
return false;
}
}
// save to the cache
slotCache.hash.insert(cacheKey, slotData);
- object->setProperty(cachePropertyName, qVariantFromValue(slotCache));
+ object->setProperty(cachePropertyName, QVariant::fromValue(slotCache));
// found the slot to be called
deliverCall(object, flags, msg, slotData.metaTypes, slotData.slotIdx);
diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp
index 78abf94168..b6cf1fd6d2 100644
--- a/src/dbus/qdbusinternalfilters.cpp
+++ b/src/dbus/qdbusinternalfilters.cpp
@@ -264,7 +264,7 @@ QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node
return propertyNotFoundError(msg, interface_name, property_name);
}
- return msg.createReply(qVariantFromValue(QDBusVariant(value)));
+ return msg.createReply(QVariant::fromValue(QDBusVariant(value)));
}
enum PropertyWriteResult {
@@ -334,7 +334,7 @@ static int writeProperty(QObject *obj, const QByteArray &property_name, QVariant
// we have to demarshall before writing
void *null = 0;
QVariant other(id, null);
- if (!QDBusMetaType::demarshall(qVariantValue<QDBusArgument>(value), id, other.data())) {
+ if (!QDBusMetaType::demarshall(qvariant_cast<QDBusArgument>(value), id, other.data())) {
qWarning("QDBusConnection: type `%s' (%d) is not registered with QtDBus. "
"Use qDBusRegisterMetaType to register it",
mp.typeName(), id);
@@ -495,7 +495,7 @@ QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &n
return interfaceNotFoundError(msg, interface_name);
}
- return msg.createReply(qVariantFromValue(result));
+ return msg.createReply(QVariant::fromValue(result));
}
QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qdeclarativedebug.cpp b/src/declarative/debugger/qdeclarativedebug.cpp
index 1ffe441821..bf07080c6c 100644
--- a/src/declarative/debugger/qdeclarativedebug.cpp
+++ b/src/declarative/debugger/qdeclarativedebug.cpp
@@ -194,7 +194,7 @@ void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugOb
{
QDeclarativeDebugObjectReference obj;
obj.m_debugId = prop.m_value.toInt();
- prop.m_value = qVariantFromValue(obj);
+ prop.m_value = QVariant::fromValue(obj);
break;
}
case QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::Unknown:
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 84b0ccfb4f..c5077954b0 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -1052,63 +1052,50 @@ void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty<QObject>
o->setParent(prop->object);
}
-static inline int children_count_helper(QGraphicsObject *object)
+int QDeclarativeFlickablePrivate::data_count(QDeclarativeListProperty<QObject> *property)
{
- QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
- return d->children.count();
+ QDeclarativeItem *contentItem= static_cast<QDeclarativeFlickablePrivate*>(property->data)->contentItem;
+ return contentItem->childItems().count() + contentItem->children().count();
}
-static inline QObject *children_at_helper(QGraphicsObject *object, int index)
+QObject *QDeclarativeFlickablePrivate::data_at(QDeclarativeListProperty<QObject> *property, int index)
{
- QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
- if (index >= 0 && index < d->children.count())
- return d->children.at(index)->toGraphicsObject();
- else
- return 0;
-}
+ QDeclarativeItem *contentItem = static_cast<QDeclarativeFlickablePrivate*>(property->data)->contentItem;
-static inline void children_clear_helper(QGraphicsObject *object)
-{
- QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
- int childCount = d->children.count();
- for (int index = 0 ;index < childCount; index++)
- QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, /*newParentVariant=*/0, /*thisPointerVariant=*/0);
-}
+ int childItemCount = contentItem->childItems().count();
-int QDeclarativeFlickablePrivate::data_count(QDeclarativeListProperty<QObject> *prop)
-{
- return QDeclarativeItemPrivate::resources_count(prop) +
- children_count_helper(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem);
-}
+ if (index < 0)
+ return 0;
+
+ if (index < childItemCount) {
+ return contentItem->childItems().at(index)->toGraphicsObject();
+ } else {
+ return contentItem->children().at(index - childItemCount);
+ }
-QObject *QDeclarativeFlickablePrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
-{
- int resourcesCount = QDeclarativeItemPrivate::resources_count(prop);
- if (i < resourcesCount)
- return QDeclarativeItemPrivate::resources_at(prop, i);
- const int j = i - resourcesCount;
- QGraphicsObject *contentObject = static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem;
- if (j < children_count_helper(contentObject))
- return children_at_helper(contentObject, j);
return 0;
}
-void QDeclarativeFlickablePrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
+void QDeclarativeFlickablePrivate::data_clear(QDeclarativeListProperty<QObject> *property)
{
- QDeclarativeItemPrivate::resources_clear(prop);
- QGraphicsObject *contentObject =
- static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem;
- children_clear_helper(contentObject);
+ QDeclarativeItem *contentItem = static_cast<QDeclarativeFlickablePrivate*>(property->data)->contentItem;
+
+ const QList<QGraphicsItem*> graphicsItems = contentItem->childItems();
+ for (int i = 0; i < graphicsItems.count(); i++)
+ contentItem->scene()->removeItem(graphicsItems[i]);
+
+ const QList<QObject*> objects = contentItem->children();
+ for (int i = 0; i < objects.count(); i++)
+ objects[i]->setParent(0);
}
QDeclarativeListProperty<QObject> QDeclarativeFlickable::flickableData()
{
Q_D(QDeclarativeFlickable);
return QDeclarativeListProperty<QObject>(this, (void *)d, QDeclarativeFlickablePrivate::data_append,
- QDeclarativeFlickablePrivate::data_count,
- QDeclarativeFlickablePrivate::data_at,
- QDeclarativeFlickablePrivate::data_clear
- );
+ QDeclarativeFlickablePrivate::data_count,
+ QDeclarativeFlickablePrivate::data_at,
+ QDeclarativeFlickablePrivate::data_clear);
}
QDeclarativeListProperty<QGraphicsObject> QDeclarativeFlickable::flickableChildren()
diff --git a/src/declarative/qml/parser/qdeclarativejsengine_p.h b/src/declarative/qml/parser/qdeclarativejsengine_p.h
index 1389244d95..d0b744dcd9 100644
--- a/src/declarative/qml/parser/qdeclarativejsengine_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsengine_p.h
@@ -88,12 +88,6 @@ uint qHash(const QDeclarativeJS::NameId &id);
} // end of namespace QDeclarativeJS
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300
-//this ensures that code outside QDeclarativeJS can use the hash function
-//it also a workaround for some compilers
-inline uint qHash(const QDeclarativeJS::NameId &nameId) { return QDeclarativeJS::qHash(nameId); }
-#endif
-
namespace QDeclarativeJS {
class Lexer;
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 80db230e64..06b1ed355a 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -1291,7 +1291,7 @@ QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEn
qsreal x = ctxt->argument(0).toNumber();
qsreal y = ctxt->argument(1).toNumber();
qsreal z = ctxt->argument(2).toNumber();
- return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QVector3D(x, y, z)));
+ return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QVector3D(x, y, z)));
}
/*!
@@ -1311,14 +1311,14 @@ QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptE
QScriptValue formatArg = ctxt->argument(1);
if (formatArg.isString()) {
QString format = formatArg.toString();
- return engine->newVariant(qVariantFromValue(date.toString(format)));
+ return engine->newVariant(QVariant::fromValue(date.toString(format)));
} else if (formatArg.isNumber()) {
enumFormat = Qt::DateFormat(formatArg.toUInt32());
} else {
return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
}
}
- return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
+ return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
}
/*!
@@ -1339,14 +1339,14 @@ QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptE
QScriptValue formatArg = ctxt->argument(1);
if (formatArg.isString()) {
QString format = formatArg.toString();
- return engine->newVariant(qVariantFromValue(date.toString(format)));
+ return engine->newVariant(QVariant::fromValue(date.toString(format)));
} else if (formatArg.isNumber()) {
enumFormat = Qt::DateFormat(formatArg.toUInt32());
} else {
return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
}
}
- return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
+ return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
}
/*!
@@ -1430,14 +1430,14 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr
QScriptValue formatArg = ctxt->argument(1);
if (formatArg.isString()) {
QString format = formatArg.toString();
- return engine->newVariant(qVariantFromValue(date.toString(format)));
+ return engine->newVariant(QVariant::fromValue(date.toString(format)));
} else if (formatArg.isNumber()) {
enumFormat = Qt::DateFormat(formatArg.toUInt32());
} else {
return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
}
}
- return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
+ return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
}
#endif // QT_NO_DATESTRING
@@ -1466,7 +1466,7 @@ QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromRgbF(r, g, b, a)));
+ return engine->toScriptValue(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
}
/*!
@@ -1494,7 +1494,7 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromHslF(h, s, l, a)));
+ return engine->toScriptValue(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
}
/*!
@@ -1517,7 +1517,7 @@ QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine
if (w < 0 || h < 0)
return engine->nullValue();
- return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QRectF(x, y, w, h)));
+ return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
}
/*!
@@ -1530,7 +1530,7 @@ QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngin
return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
qsreal x = ctxt->argument(0).toNumber();
qsreal y = ctxt->argument(1).toNumber();
- return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QPointF(x, y)));
+ return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QPointF(x, y)));
}
/*!
@@ -1543,7 +1543,7 @@ QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine
return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
qsreal w = ctxt->argument(0).toNumber();
qsreal h = ctxt->argument(1).toNumber();
- return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QSizeF(w, h)));
+ return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QSizeF(w, h)));
}
/*!
@@ -1579,7 +1579,7 @@ QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEng
if (ctxt->argumentCount() == 2)
factor = ctxt->argument(1).toNumber();
color = color.lighter(int(qRound(factor*100.)));
- return qScriptValueFromValue(engine, qVariantFromValue(color));
+ return engine->toScriptValue(QVariant::fromValue(color));
}
/*!
@@ -1616,7 +1616,7 @@ QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngi
if (ctxt->argumentCount() == 2)
factor = ctxt->argument(1).toNumber();
color = color.darker(int(qRound(factor*100.)));
- return qScriptValueFromValue(engine, qVariantFromValue(color));
+ return engine->toScriptValue(QVariant::fromValue(color));
}
/*!
@@ -1854,7 +1854,7 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine
a + inv_a * color.alphaF());
}
- return qScriptValueFromValue(engine, qVariantFromValue(finalColor));
+ return engine->toScriptValue(QVariant::fromValue(finalColor));
}
QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
@@ -1884,7 +1884,7 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v
if (objOk) {
return objectClass->newQObject(obj);
} else {
- return qScriptValueFromValue(&scriptEngine, val);
+ return scriptEngine.toScriptValue(val);
}
}
diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp
index 45f277e9be..42b596a01c 100644
--- a/src/declarative/qml/qdeclarativesqldatabase.cpp
+++ b/src/declarative/qml/qdeclarativesqldatabase.cpp
@@ -237,7 +237,7 @@ static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEn
if (!qmlengine->sqlQueryClass)
qmlengine->sqlQueryClass = new QDeclarativeSqlQueryScriptClass(engine);
QScriptValue rows = engine->newObject(qmlengine->sqlQueryClass);
- rows.setData(engine->newVariant(qVariantFromValue(query)));
+ rows.setData(engine->newVariant(QVariant::fromValue(query)));
rows.setProperty(QLatin1String("item"), engine->newFunction(qmlsqldatabase_item,1), QScriptValue::SkipInEnumeration);
result.setProperty(QLatin1String("rows"),rows);
result.setProperty(QLatin1String("rowsAffected"),query.numRowsAffected());
@@ -275,7 +275,7 @@ static QScriptValue qmlsqldatabase_change_version(QScriptContext *context, QScri
QScriptValue instance = engine->newObject();
instance.setProperty(QLatin1String("executeSql"), engine->newFunction(qmlsqldatabase_executeSql,1));
- QScriptValue tx = engine->newVariant(instance,qVariantFromValue(db));
+ QScriptValue tx = engine->newVariant(instance,QVariant::fromValue(db));
QString foundvers = context->thisObject().property(QLatin1String("version")).toString();
if (from_version!=foundvers) {
@@ -319,7 +319,7 @@ static QScriptValue qmlsqldatabase_transaction_shared(QScriptContext *context, Q
QScriptValue instance = engine->newObject();
instance.setProperty(QLatin1String("executeSql"),
engine->newFunction(readOnly ? qmlsqldatabase_executeSql_readonly : qmlsqldatabase_executeSql,1));
- QScriptValue tx = engine->newVariant(instance,qVariantFromValue(db));
+ QScriptValue tx = engine->newVariant(instance,QVariant::fromValue(db));
db.transaction();
callback.call(QScriptValue(), QScriptValueList() << tx);
@@ -403,7 +403,7 @@ static QScriptValue qmlsqldatabase_open_sync(QScriptContext *context, QScriptEng
instance.setProperty(QLatin1String("version"), version, QScriptValue::ReadOnly);
instance.setProperty(QLatin1String("changeVersion"), engine->newFunction(qmlsqldatabase_change_version,3));
- QScriptValue result = engine->newVariant(instance,qVariantFromValue(database));
+ QScriptValue result = engine->newVariant(instance,QVariant::fromValue(database));
if (created && dbcreationCallback.isFunction()) {
dbcreationCallback.call(QScriptValue(), QScriptValueList() << result);
diff --git a/src/declarative/qml/qdeclarativestringconverters.cpp b/src/declarative/qml/qdeclarativestringconverters.cpp
index 7534a2c0c5..8ec68ff7a4 100644
--- a/src/declarative/qml/qdeclarativestringconverters.cpp
+++ b/src/declarative/qml/qdeclarativestringconverters.cpp
@@ -92,7 +92,7 @@ QVariant QDeclarativeStringConverters::variantFromString(const QString &s)
QSizeF sz = sizeFFromString(s, &ok);
if (ok) return QVariant(sz);
QVector3D v = vector3DFromString(s, &ok);
- if (ok) return qVariantFromValue(v);
+ if (ok) return QVariant::fromValue(v);
return QVariant(s);
}
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index 789116e2da..509ca6bb5f 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -331,7 +331,7 @@ QVariant QDeclarativeWorkerScriptEnginePrivate::scriptValueToVariant(const QScri
QDeclarativeListModelWorkerAgent *agent = lm->agent();
if (agent) {
QDeclarativeListModelWorkerAgent::VariantRef v(agent);
- return qVariantFromValue(v);
+ return QVariant::fromValue(v);
} else {
return QVariant();
}
diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
index 332acc4f32..adfdbb380b 100644
--- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp
+++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
@@ -58,6 +58,8 @@
#include <QtCore/qstack.h>
#include <QtCore/qdebug.h>
+#include <QtCore/QStringBuilder>
+
#ifndef QT_NO_XMLSTREAMREADER
// From DOM-Level-3-Core spec
@@ -510,7 +512,7 @@ QScriptValue Node::create(QScriptEngine *engine, NodeImpl *data)
node.d = data;
if (data) A(data);
- return engine->newVariant(instance, qVariantFromValue(node));
+ return engine->newVariant(instance, QVariant::fromValue(node));
}
QScriptValue Element::prototype(QScriptEngine *engine)
@@ -710,7 +712,7 @@ QScriptValue Document::load(QScriptEngine *engine, const QByteArray &data)
instance.setPrototype(Document::prototype(engine));
Node documentNode;
documentNode.d = document;
- return engine->newVariant(instance, qVariantFromValue(documentNode));
+ return engine->newVariant(instance, QVariant::fromValue(documentNode));
}
Node::Node()
@@ -761,7 +763,7 @@ QScriptValue NamedNodeMap::create(QScriptEngine *engine, NodeImpl *data, QList<N
map.list = list;
if (data) A(data);
- instance.setData(engine->newVariant(qVariantFromValue(map)));
+ instance.setData(engine->newVariant(QVariant::fromValue(map)));
if (!QDeclarativeScriptEngine::get(engine)->namedNodeMapClass)
QDeclarativeScriptEngine::get(engine)->namedNodeMapClass= new NamedNodeMapClass(engine);
@@ -818,7 +820,7 @@ QScriptValue NodeList::create(QScriptEngine *engine, NodeImpl *data)
list.d = data;
if (data) A(data);
- instance.setData(engine->newVariant(qVariantFromValue(list)));
+ instance.setData(engine->newVariant(QVariant::fromValue(list)));
if (!QDeclarativeScriptEngine::get(engine)->nodeListClass)
QDeclarativeScriptEngine::get(engine)->nodeListClass= new NodeListClass(engine);
@@ -1090,10 +1092,9 @@ QString QDeclarativeXMLHttpRequest::headers()
foreach (const HeaderPair &header, m_headersList) {
if (ret.length())
- ret.append(QString::fromUtf8("\r\n"));
- ret.append(QString::fromUtf8(header.first));
- ret.append(QString::fromUtf8(": "));
- ret.append(QString::fromUtf8(header.second));
+ ret.append(QLatin1String("\r\n"));
+ ret = ret % QString::fromUtf8(header.first) % QLatin1String(": ")
+ % QString::fromUtf8(header.second);
}
return ret;
}
@@ -1105,9 +1106,9 @@ void QDeclarativeXMLHttpRequest::fillHeadersList()
m_headersList.clear();
foreach (const QByteArray &header, headerList) {
HeaderPair pair (header.toLower(), m_network->rawHeader(header));
- if (pair.first == "set-cookie" ||
- pair.first == "set-cookie2")
- continue;
+ if (pair.first == "set-cookie" ||
+ pair.first == "set-cookie2")
+ continue;
m_headersList << pair;
}
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index ea3da254ce..3a96f98063 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -2940,4 +2940,8 @@ void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions,
}
}
+QDeclarativeScriptActionPrivate::QDeclarativeScriptActionPrivate()
+ : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {}
+
+
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h
index cdd50411d6..8cb17e4ea7 100644
--- a/src/declarative/util/qdeclarativeanimation_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p.h
@@ -63,7 +63,7 @@ QT_MODULE(Declarative)
class QDeclarativeAbstractAnimationPrivate;
class QDeclarativeAnimationGroup;
-class Q_AUTOTEST_EXPORT QDeclarativeAbstractAnimation : public QObject, public QDeclarativePropertyValueSource, public QDeclarativeParserStatus
+class Q_DECLARATIVE_EXPORT QDeclarativeAbstractAnimation : public QObject, public QDeclarativePropertyValueSource, public QDeclarativeParserStatus
{
Q_OBJECT
Q_DECLARE_PRIVATE(QDeclarativeAbstractAnimation)
diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h
index e38580cc1f..26c04d4317 100644
--- a/src/declarative/util/qdeclarativeanimation_p_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p_p.h
@@ -247,8 +247,7 @@ class QDeclarativeScriptActionPrivate : public QDeclarativeAbstractAnimationPriv
{
Q_DECLARE_PUBLIC(QDeclarativeScriptAction)
public:
- QDeclarativeScriptActionPrivate()
- : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {}
+ QDeclarativeScriptActionPrivate();
void init();
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 32632383ae..5ce95e90f4 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -800,7 +800,7 @@ void QDeclarativeListModelParser::setCustomData(QObject *obj, const QByteArray &
{
ModelNode *n = nodes.top();
ModelNode *n2 = new ModelNode(rv->m_nested);
- n->values << qVariantFromValue(n2);
+ n->values << QVariant::fromValue(n2);
nodes.push(n2);
if (processingSet)
n->isArray = true;
@@ -1339,7 +1339,7 @@ bool NestedListModel::insert(int index, const QScriptValue& valuemap)
ModelNode *mn = new ModelNode(this);
mn->listIndex = index;
mn->setObjectValue(valuemap);
- _root->values.insert(index,qVariantFromValue(mn));
+ _root->values.insert(index,QVariant::fromValue(mn));
return true;
}
@@ -1513,7 +1513,7 @@ void ModelNode::setListValue(const QScriptValue& valuelist) {
value->listIndex = i;
value->values << v.toVariant();
}
- values.append(qVariantFromValue(value));
+ values.append(QVariant::fromValue(value));
}
}
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index 8f06858c5d..7b8861023a 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -702,6 +702,23 @@ void QDeclarativeView::paintEvent(QPaintEvent *event)
if (frameRateDebug())
qDebug() << "paintEvent:" << d->frameTimer.elapsed() << "time since last frame:" << time;
+
+#if QT_SHOW_DECLARATIVEVIEW_FPS
+ static QTime timer;
+ static int frames;
+
+ if (frames == 0) {
+ timer.start();
+ } else if (timer.elapsed() > 5000) {
+ qreal avgtime = timer.elapsed() / (qreal) frames;
+ qDebug("Average time per frame: %f ms (%i fps)", avgtime, int(1000 / avgtime));
+ timer.start();
+ frames = 0;
+ }
+ ++frames;
+ scene()->update();
+#endif
+
}
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index f0ed80b65e..870a523af0 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -806,7 +806,7 @@ QScriptValue QDeclarativeXmlListModel::get(int index) const
QScriptValue sv = sengine->newObject();
for (int i=0; i<d->roleObjects.count(); i++)
- sv.setProperty(d->roleObjects[i]->name(), qScriptValueFromValue(sengine, d->data.value(i).value(index)));
+ sv.setProperty(d->roleObjects[i]->name(), sengine->toScriptValue(d->data.value(i).value(index)));
return sv;
}
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index 0921bdbe9e..a6d1dbde19 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -409,13 +409,18 @@ static void qAccessibleCleanup()
/*!
\typedef QAccessible::InterfaceFactory
- A function pointer type. Use a function with this prototype to install
- interface factories with installFactory().
+ This is a typedef for a pointer to a function with the following
+ signature:
- The function receives a QObject pointer. If the QObject
- provides a QAccessibleInterface, it sets the second parameter to
- point to the corresponding QAccessibleInterface, and returns true;
- otherwise returns false.
+ \snippet doc/src/snippets/code/src_gui_accessible_qaccessible.cpp 1
+
+ The function receives a QString and a QObject pointer, where the
+ QString is the key identifying the interface. The QObject is used
+ to pass on to the QAccessibleInterface so that it can hold a reference
+ to it.
+
+ If the key and the QObject does not have a corresponding
+ QAccessibleInterface, a null-pointer will be returned.
Installed factories are called by queryAccessibilityInterface() until
one provides an interface.
diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp
index 7b2e7ce4bb..3a4809e5b4 100644
--- a/src/gui/accessible/qaccessibleobject.cpp
+++ b/src/gui/accessible/qaccessibleobject.cpp
@@ -276,7 +276,7 @@ QAccessible::Relation QAccessibleApplication::relationTo(int child, const
for (int i = 0; i < tlw.count(); ++i) {
QWidget *w = tlw.at(i);
- QObjectList cl = qFindChildren<QObject *>(w, QString());
+ QObjectList cl = w->findChildren<QObject *>(QString());
if (cl.contains(o))
return Ancestor;
}
diff --git a/src/gui/accessible/qaccessiblewidget.cpp b/src/gui/accessible/qaccessiblewidget.cpp
index 7c13367701..5b439a9a13 100644
--- a/src/gui/accessible/qaccessiblewidget.cpp
+++ b/src/gui/accessible/qaccessiblewidget.cpp
@@ -1015,7 +1015,7 @@ QVariant QAccessibleWidgetEx::invokeMethodEx(Method method, int child, const QVa
case ListSupportedMethods: {
QSet<QAccessible::Method> set;
set << ListSupportedMethods << ForegroundColor << BackgroundColor;
- return qVariantFromValue(set);
+ return QVariant::fromValue(set);
}
case ForegroundColor:
return widget()->palette().color(widget()->foregroundRole());
diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
index 9e0437c5bf..5a791fc0f0 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/gui/dialogs/qdialog.cpp
@@ -337,7 +337,7 @@ void QDialogPrivate::setDefault(QPushButton *pushButton)
{
Q_Q(QDialog);
bool hasMain = false;
- QList<QPushButton*> list = qFindChildren<QPushButton*>(q);
+ QList<QPushButton*> list = q->findChildren<QPushButton*>();
for (int i=0; i<list.size(); ++i) {
QPushButton *pb = list.at(i);
if (pb->window() == q) {
@@ -372,7 +372,7 @@ void QDialogPrivate::setMainDefault(QPushButton *pushButton)
void QDialogPrivate::hideDefault()
{
Q_Q(QDialog);
- QList<QPushButton*> list = qFindChildren<QPushButton*>(q);
+ QList<QPushButton*> list = q->findChildren<QPushButton*>();
for (int i=0; i<list.size(); ++i) {
list.at(i)->setDefault(false);
}
@@ -675,7 +675,7 @@ void QDialog::keyPressEvent(QKeyEvent *e)
switch (e->key()) {
case Qt::Key_Enter:
case Qt::Key_Return: {
- QList<QPushButton*> list = qFindChildren<QPushButton*>(this);
+ QList<QPushButton*> list = findChildren<QPushButton*>();
for (int i=0; i<list.size(); ++i) {
QPushButton *pb = list.at(i);
if (pb->isDefault() && pb->isVisible()) {
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index cb74a3c9a5..a0dca5d719 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -2209,9 +2209,9 @@ void QFileDialogPrivate::createWidgets()
#ifndef QT_NO_FSCOMPLETER
completer = new QFSCompleter(model, q);
qFileDialogUi->fileNameEdit->setCompleter(completer);
+#endif // QT_NO_FSCOMPLETER
QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
q, SLOT(_q_autoCompleteFileName(QString)));
-#endif // QT_NO_FSCOMPLETER
QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
q, SLOT(_q_updateOkButton()));
diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp
index 8a6190fd57..b8aafe3134 100644
--- a/src/gui/dialogs/qfilesystemmodel.cpp
+++ b/src/gui/dialogs/qfilesystemmodel.cpp
@@ -1290,6 +1290,10 @@ QString QFileSystemModelPrivate::filePath(const QModelIndex &index) const
if ((fullPath.length() > 2) && fullPath[0] == QLatin1Char('/') && fullPath[1] == QLatin1Char('/'))
fullPath = fullPath.mid(1);
#endif
+#if defined(Q_OS_WIN)
+ if (fullPath.length() == 2 && fullPath.endsWith(QLatin1Char(':')))
+ fullPath.append(QLatin1Char('/'));
+#endif
return fullPath;
}
@@ -1608,6 +1612,14 @@ bool QFileSystemModel::event(QEvent *event)
return QAbstractItemModel::event(event);
}
+bool QFileSystemModel::rmdir(const QModelIndex &aindex) const
+{
+ QString path = filePath(aindex);
+ QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
+ d->fileInfoGatherer.removePath(path);
+ return QDir().rmdir(path);
+}
+
/*!
\internal
diff --git a/src/gui/dialogs/qfilesystemmodel.h b/src/gui/dialogs/qfilesystemmodel.h
index d8178c70b0..741f22be89 100644
--- a/src/gui/dialogs/qfilesystemmodel.h
+++ b/src/gui/dialogs/qfilesystemmodel.h
@@ -139,7 +139,7 @@ public:
QDateTime lastModified(const QModelIndex &index) const;
QModelIndex mkdir(const QModelIndex &parent, const QString &name);
- inline bool rmdir(const QModelIndex &index) const;
+ bool rmdir(const QModelIndex &index) const; // ### Qt5: should not be const
inline QString fileName(const QModelIndex &index) const;
inline QIcon fileIcon(const QModelIndex &index) const;
QFile::Permissions permissions(const QModelIndex &index) const;
@@ -163,8 +163,6 @@ private:
friend class QFileDialogPrivate;
};
-inline bool QFileSystemModel::rmdir(const QModelIndex &aindex) const
-{ QDir dir; return dir.rmdir(filePath(aindex)); }
inline QString QFileSystemModel::fileName(const QModelIndex &aindex) const
{ return aindex.data(Qt::DisplayRole).toString(); }
inline QIcon QFileSystemModel::fileIcon(const QModelIndex &aindex) const
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp
index fe25b0f807..f849996151 100644
--- a/src/gui/dialogs/qmessagebox.cpp
+++ b/src/gui/dialogs/qmessagebox.cpp
@@ -412,7 +412,7 @@ void QMessageBoxPrivate::updateSize()
void QMessageBoxPrivate::hideSpecial()
{
Q_Q(QMessageBox);
- QList<QPushButton*> list = qFindChildren<QPushButton*>(q);
+ QList<QPushButton*> list = q->findChildren<QPushButton*>();
for (int i=0; i<list.size(); ++i) {
QPushButton *pb = list.at(i);
QString text = pb->text();
@@ -1266,7 +1266,7 @@ bool QMessageBox::event(QEvent *e)
(e->type() == QEvent::OkRequest)
? QApplication::translate("QMessageBox", "OK")
: QApplication::translate("QMessageBox", "Help");
- QList<QPushButton*> list = qFindChildren<QPushButton*>(this);
+ QList<QPushButton*> list = findChildren<QPushButton*>();
for (int i=0; i<list.size(); ++i) {
QPushButton *pb = list.at(i);
if (pb->text() == bName) {
@@ -1513,7 +1513,7 @@ static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
int(defaultButton), 0);
QMessageBox msgBox(icon, title, text, QMessageBox::NoButton, parent);
- QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&msgBox);
+ QDialogButtonBox *buttonBox = msgBox.findChild<QDialogButtonBox*>();
Q_ASSERT(buttonBox != 0);
uint mask = QMessageBox::FirstButton;
diff --git a/src/gui/dialogs/qnspanelproxy_mac.mm b/src/gui/dialogs/qnspanelproxy_mac.mm
index 0bd5c63f80..0e8d64d09c 100644
--- a/src/gui/dialogs/qnspanelproxy_mac.mm
+++ b/src/gui/dialogs/qnspanelproxy_mac.mm
@@ -42,6 +42,7 @@
#include <qdialogbuttonbox.h>
#if defined(Q_WS_MAC)
#include <private/qt_mac_p.h>
+#include <private/qcocoaintrospection_p.h>
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <objc/objc-class.h>
@@ -137,46 +138,6 @@ QT_USE_NAMESPACE
QT_BEGIN_NAMESPACE
-void macStartIntercept(SEL originalSel, SEL fakeSel, Class baseClass, Class proxyClass)
-{
-#ifndef QT_MAC_USE_COCOA
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
-#endif
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- // The following code replaces the _implementation_ for the selector we want to hack
- // (originalSel) with the implementation found in proxyClass. Then it creates
- // a new 'backup' method inside baseClass containing the old, original,
- // implementation (fakeSel). You can let the proxy implementation of originalSel
- // call fakeSel if needed (similar approach to calling a super class implementation).
- // fakeSel must also be implemented in proxyClass, as the signature is used
- // as template for the method one we add into baseClass.
- // NB: You will typically never create any instances of proxyClass; we use it
- // only for stealing its contents and put it into baseClass.
- Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
- Method newMethod = class_getInstanceMethod(proxyClass, originalSel);
- Method fakeMethod = class_getInstanceMethod(proxyClass, fakeSel);
-
- IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(newMethod));
- class_addMethod(baseClass, fakeSel, originalImp, method_getTypeEncoding(fakeMethod));
-#endif
- }
-}
-
-void macStopIntercept(SEL originalSel, SEL fakeSel, Class baseClass, Class /* proxyClass */)
-{
-#ifndef QT_MAC_USE_COCOA
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
-#endif
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
- Method fakeMethodInBaseClass = class_getInstanceMethod(baseClass, fakeSel);
- method_setImplementation(originalMethod, method_getImplementation(fakeMethodInBaseClass));
-#endif
- }
-}
-
/*
Intercept the NSColorPanel constructor if the shared
color panel doesn't exist yet. What's going on here is
@@ -188,12 +149,18 @@ void macStopIntercept(SEL originalSel, SEL fakeSel, Class baseClass, Class /* pr
*/
void macStartInterceptNSPanelCtor()
{
- macStartIntercept(@selector(initWithContentRect:styleMask:backing:defer:),
- @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:),
- [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]);
- macStartIntercept(@selector(initWithContentRect:styleMask:backing:defer:screen:),
- @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:),
- [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]);
+ qt_cocoa_change_implementation(
+ [NSPanel class],
+ @selector(initWithContentRect:styleMask:backing:defer:),
+ [QT_MANGLE_NAMESPACE(QNSPanelProxy) class],
+ @selector(initWithContentRect:styleMask:backing:defer:),
+ @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:));
+ qt_cocoa_change_implementation(
+ [NSPanel class],
+ @selector(initWithContentRect:styleMask:backing:defer:screen:),
+ [QT_MANGLE_NAMESPACE(QNSPanelProxy) class],
+ @selector(initWithContentRect:styleMask:backing:defer:screen:),
+ @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:));
}
/*
@@ -201,12 +168,14 @@ void macStartInterceptNSPanelCtor()
*/
void macStopInterceptNSPanelCtor()
{
- macStopIntercept(@selector(initWithContentRect:styleMask:backing:defer:screen:),
- @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:),
- [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]);
- macStopIntercept(@selector(initWithContentRect:styleMask:backing:defer:),
- @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:),
- [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]);
+ qt_cocoa_change_back_implementation(
+ [NSPanel class],
+ @selector(initWithContentRect:styleMask:backing:defer:screen:),
+ @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:));
+ qt_cocoa_change_back_implementation(
+ [NSPanel class],
+ @selector(initWithContentRect:styleMask:backing:defer:),
+ @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:));
}
/*
@@ -216,8 +185,12 @@ void macStopInterceptNSPanelCtor()
void macStartInterceptWindowTitle(QWidget *window)
{
currentWindow = window;
- macStartIntercept(@selector(setTitle:), @selector(qt_fakeSetTitle:),
- [NSWindow class], [QT_MANGLE_NAMESPACE(QNSWindowProxy) class]);
+ qt_cocoa_change_implementation(
+ [NSWindow class],
+ @selector(setTitle:),
+ [QT_MANGLE_NAMESPACE(QNSWindowProxy) class],
+ @selector(setTitle:),
+ @selector(qt_fakeSetTitle:));
}
/*
@@ -226,8 +199,10 @@ void macStartInterceptWindowTitle(QWidget *window)
void macStopInterceptWindowTitle()
{
currentWindow = 0;
- macStopIntercept(@selector(setTitle:), @selector(qt_fakeSetTitle:),
- [NSWindow class], [QT_MANGLE_NAMESPACE(QNSWindowProxy) class]);
+ qt_cocoa_change_back_implementation(
+ [NSWindow class],
+ @selector(setTitle:),
+ @selector(qt_fakeSetTitle:));
}
/*
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp
index 3fc7f1071b..41048346a3 100644
--- a/src/gui/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp
@@ -589,6 +589,18 @@ void QGraphicsGridLayout::removeAt(int index)
}
/*!
+ Removes the layout item \a item without destroying it.
+ Ownership of the item is transferred to the caller.
+
+ \sa addItem()
+*/
+void QGraphicsGridLayout::removeItem(QGraphicsLayoutItem *item)
+{
+ Q_D(QGraphicsGridLayout);
+ int index = d->engine.indexOf(item);
+ removeAt(index);
+}
+/*!
\reimp
*/
void QGraphicsGridLayout::invalidate()
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.h b/src/gui/graphicsview/qgraphicsgridlayout.h
index 6580a026ad..d10235cc6a 100644
--- a/src/gui/graphicsview/qgraphicsgridlayout.h
+++ b/src/gui/graphicsview/qgraphicsgridlayout.h
@@ -109,11 +109,12 @@ public:
int columnCount() const;
QGraphicsLayoutItem *itemAt(int row, int column) const;
-
+
// inherited from QGraphicsLayout
int count() const;
QGraphicsLayoutItem *itemAt(int index) const;
void removeAt(int index);
+ void removeItem(QGraphicsLayoutItem *item);
void invalidate();
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index b404692e68..096be63c7d 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1703,12 +1703,12 @@ void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
return;
const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
- qVariantFromValue<QGraphicsItem *>(newParent)));
- newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
+ QVariant::fromValue<QGraphicsItem *>(newParent)));
+ newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
if (newParent == d_ptr->parent)
return;
- const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this));
+ const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
}
@@ -2132,7 +2132,7 @@ void QGraphicsItem::setToolTip(const QString &toolTip)
*/
QCursor QGraphicsItem::cursor() const
{
- return qVariantValue<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
+ return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
}
/*!
@@ -2152,8 +2152,8 @@ QCursor QGraphicsItem::cursor() const
*/
void QGraphicsItem::setCursor(const QCursor &cursor)
{
- const QVariant cursorVariant(itemChange(ItemCursorChange, qVariantFromValue<QCursor>(cursor)));
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qVariantValue<QCursor>(cursorVariant));
+ const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
d_ptr->hasCursor = 1;
if (d_ptr->scene) {
d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
@@ -2279,7 +2279,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
// Schedule redrawing
if (update) {
- QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
+ QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
if (c)
c->purge();
if (scene) {
@@ -3706,7 +3706,7 @@ void QGraphicsItem::setPos(const QPointF &pos)
}
// Notify the item that the position is changing.
- const QVariant newPosVariant(itemChange(ItemPositionChange, qVariantFromValue<QPointF>(pos)));
+ const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
QPointF newPos = newPosVariant.toPointF();
if (newPos == d_ptr->pos)
return;
@@ -4060,7 +4060,7 @@ void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
if (d_ptr->flags & ItemSendsGeometryChanges) {
// Notify the item that the origin point is changing.
const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
- qVariantFromValue<QPointF>(origin)));
+ QVariant::fromValue<QPointF>(origin)));
newOrigin = newOriginVariant.toPointF();
}
@@ -4079,7 +4079,7 @@ void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
// Send post-notification.
if (d_ptr->flags & ItemSendsGeometryChanges)
- itemChange(ItemTransformOriginPointHasChanged, qVariantFromValue<QPointF>(newOrigin));
+ itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
}
/*!
@@ -4341,8 +4341,8 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
}
// Notify the item that the transformation matrix is changing.
- const QVariant newMatrixVariant = qVariantFromValue<QMatrix>(newTransform.toAffine());
- newTransform = QTransform(qVariantValue<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
+ const QVariant newMatrixVariant = QVariant::fromValue<QMatrix>(newTransform.toAffine());
+ newTransform = QTransform(qvariant_cast<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
if (d_ptr->transformData->transform == newTransform)
return;
@@ -4350,7 +4350,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
d_ptr->setTransformHelper(newTransform);
// Send post-notification.
- itemChange(ItemTransformHasChanged, qVariantFromValue<QTransform>(newTransform));
+ itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
}
/*!
@@ -4391,8 +4391,8 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
// Notify the item that the transformation matrix is changing.
const QVariant newTransformVariant(itemChange(ItemTransformChange,
- qVariantFromValue<QTransform>(newTransform)));
- newTransform = qVariantValue<QTransform>(newTransformVariant);
+ QVariant::fromValue<QTransform>(newTransform)));
+ newTransform = qvariant_cast<QTransform>(newTransformVariant);
if (d_ptr->transformData->transform == newTransform)
return;
@@ -5245,7 +5245,7 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c
qreal QGraphicsItem::boundingRegionGranularity() const
{
return d_ptr->hasBoundingRegionGranularity
- ? qVariantValue<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
+ ? qvariant_cast<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
: 0;
}
@@ -5281,7 +5281,7 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
}
d_ptr->hasBoundingRegionGranularity = 1;
d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
- qVariantFromValue<qreal>(granularity));
+ QVariant::fromValue<qreal>(granularity));
}
/*!
@@ -5456,7 +5456,7 @@ void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
*/
QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
{
- return (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
+ return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
}
/*!
@@ -5464,11 +5464,11 @@ QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
*/
QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
{
- QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
+ QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
if (!c) {
QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
c = new QGraphicsItemCache;
- that->setExtra(ExtraCacheData, qVariantFromValue<void *>(c));
+ that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
}
return c;
}
@@ -5478,7 +5478,7 @@ QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
*/
void QGraphicsItemPrivate::removeExtraItemCache()
{
- QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
+ QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
if (c) {
c->purge();
delete c;
@@ -8085,6 +8085,8 @@ QPen QAbstractGraphicsShapeItem::pen() const
void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
{
Q_D(QAbstractGraphicsShapeItem);
+ if (d->pen == pen)
+ return;
prepareGeometryChange();
d->pen = pen;
d->boundingRect = QRectF();
@@ -8115,6 +8117,8 @@ QBrush QAbstractGraphicsShapeItem::brush() const
void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
{
Q_D(QAbstractGraphicsShapeItem);
+ if (d->brush == brush)
+ return;
d->brush = brush;
update();
}
@@ -9245,6 +9249,8 @@ QPen QGraphicsLineItem::pen() const
void QGraphicsLineItem::setPen(const QPen &pen)
{
Q_D(QGraphicsLineItem);
+ if (d->pen == pen)
+ return;
prepareGeometryChange();
d->pen = pen;
update();
diff --git a/src/gui/graphicsview/qgraphicsitemanimation.cpp b/src/gui/graphicsview/qgraphicsitemanimation.cpp
index 9cb9a8dd96..9689616442 100644
--- a/src/gui/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/gui/graphicsview/qgraphicsitemanimation.cpp
@@ -49,20 +49,20 @@
The QGraphicsItemAnimation class animates a QGraphicsItem. You can
schedule changes to the item's transformation matrix at
- specified steps. The QGraphicsItemAnimation class has a
- current step value. When this value changes the transformations
- scheduled at that step are performed. The current step of the
+ specified steps. The QGraphicsItemAnimation class has a
+ current step value. When this value changes the transformations
+ scheduled at that step are performed. The current step of the
animation is set with the \c setStep() function.
QGraphicsItemAnimation will do a simple linear interpolation
- between the nearest adjacent scheduled changes to calculate the
+ between the nearest adjacent scheduled changes to calculate the
matrix. For instance, if you set the position of an item at values
0.0 and 1.0, the animation will show the item moving in a straight
- line between these positions. The same is true for scaling and
+ line between these positions. The same is true for scaling and
rotation.
It is usual to use the class with a QTimeLine. The timeline's
- \l{QTimeLine::}{valueChanged()} signal is then connected to the
+ \l{QTimeLine::}{valueChanged()} signal is then connected to the
\c setStep() slot. For example, you can set up an item for rotation
by calling \c setRotationAt() for different step values.
The animations timeline is set with the setTimeLine() function.
@@ -286,7 +286,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::posList() const
QList<QPair<qreal, QPointF> > list;
for (int i = 0; i < d->xPosition.size(); ++i)
list << QPair<qreal, QPointF>(d->xPosition.at(i).step, QPointF(d->xPosition.at(i).value, d->yPosition.at(i).value));
-
+
return list;
}
@@ -343,7 +343,7 @@ QList<QPair<qreal, qreal> > QGraphicsItemAnimation::rotationList() const
QList<QPair<qreal, qreal> > list;
for (int i = 0; i < d->rotation.size(); ++i)
list << QPair<qreal, qreal>(d->rotation.at(i).step, d->rotation.at(i).value);
-
+
return list;
}
@@ -395,7 +395,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::translationList() const
QList<QPair<qreal, QPointF> > list;
for (int i = 0; i < d->xTranslation.size(); ++i)
list << QPair<qreal, QPointF>(d->xTranslation.at(i).step, QPointF(d->xTranslation.at(i).value, d->yTranslation.at(i).value));
-
+
return list;
}
@@ -447,7 +447,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::scaleList() const
QList<QPair<qreal, QPointF> > list;
for (int i = 0; i < d->horizontalScale.size(); ++i)
list << QPair<qreal, QPointF>(d->horizontalScale.at(i).step, QPointF(d->horizontalScale.at(i).value, d->verticalScale.at(i).value));
-
+
return list;
}
@@ -499,7 +499,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::shearList() const
QList<QPair<qreal, QPointF> > list;
for (int i = 0; i < d->horizontalShear.size(); ++i)
list << QPair<qreal, QPointF>(d->horizontalShear.at(i).step, QPointF(d->horizontalShear.at(i).value, d->verticalShear.at(i).value));
-
+
return list;
}
diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp
index 86b4589ee4..91f386f0bc 100644
--- a/src/gui/graphicsview/qgraphicslayout.cpp
+++ b/src/gui/graphicsview/qgraphicslayout.cpp
@@ -145,7 +145,7 @@ QT_BEGIN_NAMESPACE
/*!
Contructs a QGraphicsLayout object.
-
+
\a parent is passed to QGraphicsLayoutItem's constructor and the
QGraphicsLayoutItem's isLayout argument is set to \e true.
@@ -259,7 +259,7 @@ void QGraphicsLayout::activate()
return;
d->activateRecursive(this);
-
+
// we don't call activate on a sublayout, but somebody might.
// Therefore, we walk to the parentitem of the toplevel layout.
QGraphicsLayoutItem *parentItem = this;
@@ -270,7 +270,7 @@ void QGraphicsLayout::activate()
Q_ASSERT(!parentItem->isLayout());
setGeometry(parentItem->contentsRect()); // relayout children
-
+
// ### bug, should be parentItem ?
parentLayoutItem()->updateGeometry(); // bubble up; will set activated to false
// ### too many resizes? maybe we should walk up the chain to the
@@ -307,7 +307,7 @@ void QGraphicsLayout::invalidate()
// does not call the base implementation? In addition, updateGeometry()
// does more than we need.
layoutItem->d_func()->sizeHintCacheDirty = true;
- layoutItem = layoutItem->parentLayoutItem();
+ layoutItem = layoutItem->parentLayoutItem();
}
if (layoutItem)
layoutItem->d_func()->sizeHintCacheDirty = true;
@@ -347,7 +347,7 @@ void QGraphicsLayout::updateGeometry()
widget. QGraphicsLayout uses this event handler to listen for layout
related events such as geometry changes, layout changes or layout
direction changes.
-
+
\a e is a pointer to the event.
You can reimplement this event handler to track similar events for your
diff --git a/src/gui/graphicsview/qgraphicslayout_p.cpp b/src/gui/graphicsview/qgraphicslayout_p.cpp
index 88652ecdc8..163fc65301 100644
--- a/src/gui/graphicsview/qgraphicslayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicslayout_p.cpp
@@ -136,13 +136,13 @@ static bool removeLayoutItemFromLayout(QGraphicsLayout *lay, QGraphicsLayoutItem
/*!
\internal
- This function is called from subclasses to add a layout item \a layoutItem
+ This function is called from subclasses to add a layout item \a layoutItem
to a layout.
It takes care of automatically reparenting graphics items, if needed.
If \a layoutItem is a is already in a layout, it will remove it from that layout.
-
+
*/
void QGraphicsLayoutPrivate::addChildLayoutItem(QGraphicsLayoutItem *layoutItem)
{
@@ -150,14 +150,14 @@ void QGraphicsLayoutPrivate::addChildLayoutItem(QGraphicsLayoutItem *layoutItem)
if (QGraphicsLayoutItem *maybeLayout = layoutItem->parentLayoutItem()) {
if (maybeLayout->isLayout())
removeLayoutItemFromLayout(static_cast<QGraphicsLayout*>(maybeLayout), layoutItem);
- }
+ }
layoutItem->setParentLayoutItem(q);
if (layoutItem->isLayout()) {
if (QGraphicsItem *parItem = parentItem()) {
static_cast<QGraphicsLayout*>(layoutItem)->d_func()->reparentChildItems(parItem);
}
} else {
- if (QGraphicsItem *item = layoutItem->graphicsItem()) {
+ if (QGraphicsItem *item = layoutItem->graphicsItem()) {
QGraphicsItem *newParent = parentItem();
QGraphicsItem *oldParent = item->parentItem();
if (oldParent == newParent || !newParent)
@@ -182,7 +182,7 @@ void QGraphicsLayoutPrivate::activateRecursive(QGraphicsLayoutItem *item)
QGraphicsLayout *layout = static_cast<QGraphicsLayout *>(item);
if (layout->d_func()->activated)
layout->invalidate();
-
+
for (int i = layout->count() - 1; i >= 0; --i) {
QGraphicsLayoutItem *childItem = layout->itemAt(i);
if (childItem)
@@ -194,5 +194,5 @@ void QGraphicsLayoutPrivate::activateRecursive(QGraphicsLayoutItem *item)
QT_END_NAMESPACE
-
+
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicslayout_p.h b/src/gui/graphicsview/qgraphicslayout_p.h
index 3083555088..5c8e706d15 100644
--- a/src/gui/graphicsview/qgraphicslayout_p.h
+++ b/src/gui/graphicsview/qgraphicslayout_p.h
@@ -84,7 +84,7 @@ class QLayoutStyleInfo
public:
inline QLayoutStyleInfo() { invalidate(); }
inline QLayoutStyleInfo(QStyle *style, QWidget *widget)
- : m_valid(true), m_style(style), m_widget(widget)
+ : m_valid(true), m_style(style), m_widget(widget)
{
Q_ASSERT(style);
if (widget) //###
@@ -112,7 +112,7 @@ public:
return m_defaultSpacing[o - 1];
}
- inline qreal perItemSpacing(QSizePolicy::ControlType control1,
+ inline qreal perItemSpacing(QSizePolicy::ControlType control1,
QSizePolicy::ControlType control2,
Qt::Orientation orientation) const
{
@@ -132,7 +132,7 @@ class Q_AUTOTEST_EXPORT QGraphicsLayoutPrivate : public QGraphicsLayoutItemPriva
Q_DECLARE_PUBLIC(QGraphicsLayout)
public:
- QGraphicsLayoutPrivate() : QGraphicsLayoutItemPrivate(0, true), left(-1.0), top(-1.0), right(-1.0), bottom(-1.0),
+ QGraphicsLayoutPrivate() : QGraphicsLayoutItemPrivate(0, true), left(-1.0), top(-1.0), right(-1.0), bottom(-1.0),
activated(true) { }
void reparentChildItems(QGraphicsItem *newParent);
@@ -148,7 +148,7 @@ public:
QT_END_NAMESPACE
-
+
#endif //QT_NO_GRAPHICSVIEW
#endif
diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp
index 634f68c834..34ec4e048e 100644
--- a/src/gui/graphicsview/qgraphicslayoutitem.cpp
+++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp
@@ -285,10 +285,6 @@ bool QGraphicsLayoutItemPrivate::hasHeightForWidth() const
bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const
{
- // enable this code when we add QSizePolicy::hasWidthForHeight() (For 4.8)
-#if 1
- return false;
-#else
Q_Q(const QGraphicsLayoutItem);
if (isLayout) {
const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
@@ -305,7 +301,6 @@ bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const
}
}
return q->sizePolicy().hasWidthForHeight();
-#endif
}
/*!
@@ -697,7 +692,7 @@ void QGraphicsLayoutItem::setMaximumHeight(qreal height)
is equivalent to the item's position in parent coordinates).
You must reimplement this function in a subclass of QGraphicsLayoutItem to
- receive geometry updates. The layout will call this function when it does a
+ receive geometry updates. The layout will call this function when it does a
rearrangement.
If \a rect is outside of the bounds of minimumSize and maximumSize, it
diff --git a/src/gui/graphicsview/qgraphicslayoutitem.h b/src/gui/graphicsview/qgraphicslayoutitem.h
index f707c62460..cb894a413f 100644
--- a/src/gui/graphicsview/qgraphicslayoutitem.h
+++ b/src/gui/graphicsview/qgraphicslayoutitem.h
@@ -118,7 +118,7 @@ protected:
private:
QSizeF *effectiveSizeHints(const QSizeF &constraint) const;
Q_DECLARE_PRIVATE(QGraphicsLayoutItem)
-
+
friend class QGraphicsLayout;
};
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 54fdf3f33d..7cb442f2ae 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -2544,8 +2544,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// Notify the item that its scene is changing, and allow the item to
// react.
const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue<QGraphicsScene *>(this)));
- QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
+ QVariant::fromValue<QGraphicsScene *>(this)));
+ QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
if (targetScene != this) {
if (targetScene && item->d_ptr->scene != targetScene)
targetScene->addItem(item);
@@ -2956,8 +2956,8 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
// Notify the item that it's scene is changing to 0, allowing the item to
// react.
const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue<QGraphicsScene *>(0)));
- QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
+ QVariant::fromValue<QGraphicsScene *>(0)));
+ QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
if (targetScene != 0 && targetScene != this) {
targetScene->addItem(item);
return;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index c8aca80930..d568c40867 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -3709,7 +3709,7 @@ void QGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
}
/*!
- \obsolete
+ \obsolete
Draws the items \a items in the scene using \a painter, after the
background and before the foreground are drawn. \a numItems is the number
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index 7bd9ecb918..62be800043 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -62,6 +62,7 @@
#include "qgraphicssceneevent.h"
#include <QtGui/qstyleoption.h>
#include <private/qabstractscrollarea_p.h>
+#include <private/qapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -180,21 +181,24 @@ public:
inline void dispatchPendingUpdateRequests()
{
-#ifndef Q_WS_MAC
- // QWidget::update() works slightly different on the Mac; it's not part of
- // our backing store so it needs special threatment.
- if (qt_widget_private(viewport)->paintOnScreen())
- QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest);
- else
- QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest);
-#else
- // At this point either HIViewSetNeedsDisplay (Carbon) or setNeedsDisplay: YES (Cocoa)
- // is called, which means there's a pending update request. We want to dispatch it
- // now because otherwise graphics view updates would require two
- // round-trips in the event loop before the item is painted.
- extern void qt_mac_dispatchPendingUpdateRequests(QWidget *);
- qt_mac_dispatchPendingUpdateRequests(viewport->window());
-#endif
+#ifdef Q_WS_MAC
+ // QWidget::update() works slightly different on the Mac without the raster engine;
+ // it's not part of our backing store so it needs special threatment.
+ if (QApplicationPrivate::graphics_system_name != "raster") {
+ // At this point either HIViewSetNeedsDisplay (Carbon) or setNeedsDisplay: YES (Cocoa)
+ // is called, which means there's a pending update request. We want to dispatch it
+ // now because otherwise graphics view updates would require two
+ // round-trips in the event loop before the item is painted.
+ extern void qt_mac_dispatchPendingUpdateRequests(QWidget *);
+ qt_mac_dispatchPendingUpdateRequests(viewport->window());
+ } else
+#endif // !Q_WS_MAC
+ {
+ if (qt_widget_private(viewport)->paintOnScreen())
+ QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest);
+ else
+ QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest);
+ }
}
void setUpdateClip(QGraphicsItem *);
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index 34667337b5..f99749cd94 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -46,6 +46,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/qnumeric.h>
#include "qgraphicswidget_p.h"
+#include "qgraphicslayoutitem_p.h"
#include "qgraphicslayout.h"
#include "qgraphicsscene_p.h"
#include <QtGui/qapplication.h>
@@ -415,8 +416,7 @@ static qreal minimumHeightForWidth(qreal width, qreal minh, qreal maxh,
bool heightForWidth = true)
{
qreal minimumHeightForWidth = -1;
- const QSizePolicy sp = widget->layout() ? widget->layout()->sizePolicy() : widget->sizePolicy();
- const bool hasHFW = sp.hasHeightForWidth();
+ const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
if (hasHFW == heightForWidth) {
minimumHeightForWidth = hasHFW
? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(width, -1)).height()
@@ -505,21 +505,31 @@ static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,
qreal width = qBound(min.width(), proposedRect.width(), max.width());
qreal height = qBound(min.height(), proposedRect.height(), max.height());
- QSizePolicy sp = widget->sizePolicy();
- if (const QGraphicsLayout *l = widget->layout()) {
- sp = l->sizePolicy();
- }
- const bool hasHFW = sp.hasHeightForWidth(); // || sp.hasWidthForHeight();
+ const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
+ const bool hasWFH = QGraphicsLayoutItemPrivate::get(widget)->hasWidthForHeight();
- const bool widthChanged = proposedRect.width() < widget->size().width();
- const bool heightChanged = proposedRect.height() < widget->size().height();
+ const bool widthChanged = proposedRect.width() != widget->size().width();
+ const bool heightChanged = proposedRect.height() != widget->size().height();
- if (hasHFW) {
+ if (hasHFW || hasWFH) {
if (widthChanged || heightChanged) {
- const qreal minh = min.height();
- const qreal maxh = max.height();
- const qreal proposedHFW = minimumHeightForWidth(width, minh, maxh, widget);
- if (proposedHFW > proposedRect.height()) {
+ qreal minExtent;
+ qreal maxExtent;
+ qreal constraint;
+ qreal proposed;
+ if (hasHFW) {
+ minExtent = min.height();
+ maxExtent = max.height();
+ constraint = width;
+ proposed = proposedRect.height();
+ } else {
+ // width for height
+ minExtent = min.width();
+ maxExtent = max.width();
+ constraint = height;
+ proposed = proposedRect.width();
+ }
+ if (minimumHeightForWidth(constraint, minExtent, maxExtent, widget, hasHFW) > proposed) {
QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);
width = effectiveSize.width();
height = effectiveSize.height();
diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp
index f3b20263a8..98e67811f6 100644
--- a/src/gui/graphicsview/qgridlayoutengine.cpp
+++ b/src/gui/graphicsview/qgridlayoutengine.cpp
@@ -801,6 +801,15 @@ QGridLayoutItem *QGridLayoutEngine::itemAt(int index) const
return q_items.at(index);
}
+int QGridLayoutEngine::indexOf(QGraphicsLayoutItem *item) const
+{
+ for (int i = 0; i < q_items.size(); ++i) {
+ if (item == q_items.at(i)->layoutItem())
+ return i;
+ }
+ return -1;
+}
+
int QGridLayoutEngine::effectiveFirstRow(Qt::Orientation orientation) const
{
ensureEffectiveFirstAndLastRows();
diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h
index 580af7e29c..55451d758b 100644
--- a/src/gui/graphicsview/qgridlayoutengine_p.h
+++ b/src/gui/graphicsview/qgridlayoutengine_p.h
@@ -338,6 +338,7 @@ public:
// returns the number of items inserted, which may be less than (rowCount * columnCount)
int itemCount() const;
QGridLayoutItem *itemAt(int index) const;
+ int indexOf(QGraphicsLayoutItem *item) const;
int effectiveFirstRow(Qt::Orientation orientation = Qt::Vertical) const;
int effectiveLastRow(Qt::Orientation orientation = Qt::Vertical) const;
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index faef07be51..fd591e62ba 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -71,6 +71,10 @@ public:
explicit QIcon(QIconEngineV2 *engine);
~QIcon();
QIcon &operator=(const QIcon &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QIcon &operator=(QIcon &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
operator QVariant() const;
QPixmap pixmap(const QSize &size, Mode mode = Normal, State state = Off) const;
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index ac148eec31..300e04b4ee 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -2022,6 +2022,88 @@ void QImage::fill(uint pixel)
0, 0, d->width, d->height, d->bytes_per_line);
}
+
+/*!
+ \fn void QImage::fill(Qt::GlobalColor color)
+
+ \overload
+
+ \since 4.8
+ */
+
+void QImage::fill(Qt::GlobalColor color)
+{
+ fill(QColor(color));
+}
+
+
+
+/*!
+ \fn void QImage::fill(Qt::GlobalColor color)
+
+ \overload
+
+ Fills the entire image with the given \a color.
+
+ If the depth of the image is 1, the image will be filled with 1 if
+ \a color equals Qt::color0; it will otherwise be filled with 0.
+
+ If the depth of the image is 8, the image will be filled with the
+ index corresponding the \a color in the color table if present; it
+ will otherwise be filled with 0.|
+
+ \since 4.8
+*/
+
+void QImage::fill(const QColor &color)
+{
+ if (!d)
+ return;
+ detach();
+
+ // In case we run out of memory
+ if (!d)
+ return;
+
+ if (d->depth == 32) {
+ uint pixel = color.rgba();
+ if (d->format == QImage::Format_ARGB32_Premultiplied)
+ pixel = PREMUL(pixel);
+ fill((uint) pixel);
+
+ } else if (d->depth == 16 && d->format == QImage::Format_RGB16) {
+ qrgb565 p(color.rgba());
+ fill((uint) p.rawValue());
+
+ } else if (d->depth == 1) {
+ if (color == Qt::color1)
+ fill((uint) 1);
+ else
+ fill((uint) 0);
+
+ } else if (d->depth == 8) {
+ uint pixel = 0;
+ for (int i=0; i<d->colortable.size(); ++i) {
+ if (color.rgba() == d->colortable.at(i)) {
+ pixel = i;
+ break;
+ }
+ }
+ fill(pixel);
+
+ } else {
+ QPainter p(this);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(rect(), color);
+ }
+
+}
+
+
+
+
+
+
/*!
Inverts all pixel values in the image.
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 896061ffc0..4fe7da2396 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -140,6 +140,11 @@ public:
~QImage();
QImage &operator=(const QImage &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QImage &operator=(QImage &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
+
bool isNull() const;
int devType() const;
@@ -210,6 +215,9 @@ public:
void setColorTable(const QVector<QRgb> colors);
void fill(uint pixel);
+ void fill(const QColor &color);
+ void fill(Qt::GlobalColor color);
+
bool hasAlphaChannel() const;
void setAlphaChannel(const QImage &alphaChannel);
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index ec56af2702..03ee902b78 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -1092,7 +1092,7 @@ QColor QImageReader::backgroundColor() const
if (!d->initHandler())
return QColor();
if (d->handler->supportsOption(QImageIOHandler::BackgroundColor))
- return qVariantValue<QColor>(d->handler->option(QImageIOHandler::BackgroundColor));
+ return qvariant_cast<QColor>(d->handler->option(QImageIOHandler::BackgroundColor));
return QColor();
}
diff --git a/src/gui/image/qmnghandler.cpp b/src/gui/image/qmnghandler.cpp
index cf53af0967..40f1b546a9 100644
--- a/src/gui/image/qmnghandler.cpp
+++ b/src/gui/image/qmnghandler.cpp
@@ -481,7 +481,7 @@ void QMngHandler::setOption(ImageOption option, const QVariant & value)
{
Q_D(QMngHandler);
if (option == QImageIOHandler::BackgroundColor)
- d->setBackgroundColor(qVariantValue<QColor>(value));
+ d->setBackgroundColor(qvariant_cast<QColor>(value));
}
/*! \reimp */
diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h
index 63ef42e8e7..49b0fd6708 100644
--- a/src/gui/image/qpicture.h
+++ b/src/gui/image/qpicture.h
@@ -81,6 +81,10 @@ public:
void setBoundingRect(const QRect &r);
QPicture& operator=(const QPicture &p);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QPicture &operator=(QPicture &&other)
+ { qSwap(d_ptr, other.d_ptr); return *this; }
+#endif
void detach();
bool isDetached() const;
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 1e502bd1c2..4cfadf8c5d 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -99,7 +99,7 @@ static bool qt_pixmap_thread_test()
return false;
}
#ifndef Q_WS_WIN
- if (qApp->thread() != QThread::currentThread()) {
+ if (!QApplication::testAttribute(Qt::AA_X11InitThreads) && qApp->thread() != QThread::currentThread()) {
qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
return false;
}
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index 64ca8a38a7..e9f9365f7e 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -83,6 +83,10 @@ public:
~QPixmap();
QPixmap &operator=(const QPixmap &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QPixmap &operator=(QPixmap &&other)
+ { qSwap(data, other.data); return *this; }
+#endif
operator QVariant() const;
bool isNull() const; // ### Qt 5: make inline
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index 3d9c363f71..9f8e643288 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -310,7 +310,7 @@ static int defaultScreen = -1;
QPixmap member functions
*****************************************************************************/
-static int qt_pixmap_serial = 0;
+QBasicAtomicInt qt_pixmap_serial = Q_BASIC_ATOMIC_INITIALIZER(0);
int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0;
QX11PixmapData::QX11PixmapData(PixelType type)
@@ -327,7 +327,7 @@ QPixmapData *QX11PixmapData::createCompatiblePixmapData() const
void QX11PixmapData::resize(int width, int height)
{
- setSerialNumber(++qt_pixmap_serial);
+ setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
w = width;
h = height;
@@ -410,7 +410,7 @@ struct QX11AlphaDetector
void QX11PixmapData::fromImage(const QImage &img,
Qt::ImageConversionFlags flags)
{
- setSerialNumber(++qt_pixmap_serial);
+ setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
w = img.width();
h = img.height();
@@ -2014,7 +2014,7 @@ QPixmap QX11PixmapData::transformed(const QTransform &transform,
x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
RootWindow(X11->display, xinfo.screen()),
w, h, d);
- x11Data->setSerialNumber(++qt_pixmap_serial);
+ x11Data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
#ifndef QT_NO_XRENDER
if (X11->use_xrender) {
@@ -2265,7 +2265,7 @@ void QX11PixmapData::copy(const QPixmapData *data, const QRect &rect)
const QX11PixmapData *x11Data = static_cast<const QX11PixmapData*>(data);
- setSerialNumber(++qt_pixmap_serial);
+ setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
flags &= ~Uninitialized;
xinfo = x11Data->xinfo;
@@ -2385,7 +2385,7 @@ QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
}
QX11PixmapData *data = new QX11PixmapData(depth == 1 ? QPixmapData::BitmapType : QPixmapData::PixmapType);
- data->setSerialNumber(++qt_pixmap_serial);
+ data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
data->flags = QX11PixmapData::Readonly;
data->share_mode = mode;
data->w = width;
diff --git a/src/gui/image/qtiffhandler.cpp b/src/gui/image/qtiffhandler.cpp
index de4f680245..2e8b9988ee 100644
--- a/src/gui/image/qtiffhandler.cpp
+++ b/src/gui/image/qtiffhandler.cpp
@@ -196,9 +196,12 @@ bool QTiffHandler::read(QImage *image)
uint16 bitPerSample;
if (!TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitPerSample))
bitPerSample = 1;
+ uint16 samplesPerPixel; // they may be e.g. grayscale with 2 samples per pixel
+ if (!TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel))
+ samplesPerPixel = 1;
bool grayscale = photometric == PHOTOMETRIC_MINISBLACK || photometric == PHOTOMETRIC_MINISWHITE;
- if (grayscale && bitPerSample == 1) {
+ if (grayscale && bitPerSample == 1 && samplesPerPixel == 1) {
if (image->size() != QSize(width, height) || image->format() != QImage::Format_Mono)
*image = QImage(width, height, QImage::Format_Mono);
QVector<QRgb> colortable(2);
@@ -220,7 +223,7 @@ bool QTiffHandler::read(QImage *image)
}
}
} else {
- if ((grayscale || photometric == PHOTOMETRIC_PALETTE) && bitPerSample == 8) {
+ if ((grayscale || photometric == PHOTOMETRIC_PALETTE) && bitPerSample == 8 && samplesPerPixel == 1) {
if (image->size() != QSize(width, height) || image->format() != QImage::Format_Indexed8)
*image = QImage(width, height, QImage::Format_Indexed8);
if (!image->isNull()) {
diff --git a/src/gui/itemviews/qabstractitemdelegate.cpp b/src/gui/itemviews/qabstractitemdelegate.cpp
index 0ea6d67d78..edbeeb8cd0 100644
--- a/src/gui/itemviews/qabstractitemdelegate.cpp
+++ b/src/gui/itemviews/qabstractitemdelegate.cpp
@@ -362,7 +362,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
case QEvent::ToolTip: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
QVariant tooltip = index.data(Qt::ToolTipRole);
- if (qVariantCanConvert<QString>(tooltip)) {
+ if (tooltip.canConvert<QString>()) {
QToolTip::showText(he->globalPos(), tooltip.toString(), view);
return true;
}
@@ -376,7 +376,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
case QEvent::WhatsThis: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
QVariant whatsthis = index.data(Qt::WhatsThisRole);
- if (qVariantCanConvert<QString>(whatsthis)) {
+ if (whatsthis.canConvert<QString>()) {
QWhatsThis::showText(he->globalPos(), whatsthis.toString(), view);
return true;
}
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 4ffd28407e..0842ee8258 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -79,6 +79,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate()
pressedAlreadySelected(false),
viewportEnteredNeeded(false),
state(QAbstractItemView::NoState),
+ stateBeforeAnimation(QAbstractItemView::NoState),
editTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed),
lastTrigger(QAbstractItemView::NoEditTriggers),
tabKeyNavigation(false),
@@ -652,7 +653,7 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
"QAbstractItemView::setModel",
"A model should return the exact same index "
"(including its internal id/pointer) when asked for it twice in a row.");
- Q_ASSERT_X(d->model->index(0,0).parent() == QModelIndex(),
+ Q_ASSERT_X(!d->model->index(0,0).parent().isValid(),
"QAbstractItemView::setModel",
"The parent of a top level index should be invalid");
@@ -1036,10 +1037,12 @@ void QAbstractItemView::reset()
{
Q_D(QAbstractItemView);
d->delayedReset.stop(); //make sure we stop the timer
- QList<QEditorInfo>::const_iterator it = d->editors.constBegin();
- for (; it != d->editors.constEnd(); ++it)
- d->releaseEditor(it->editor);
- d->editors.clear();
+ foreach (const QEditorInfo &info, d->indexEditorHash) {
+ if (info.widget)
+ d->releaseEditor(info.widget.data());
+ }
+ d->editorIndexHash.clear();
+ d->indexEditorHash.clear();
d->persistent.clear();
d->currentIndexSet = false;
setState(NoState);
@@ -2333,7 +2336,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
case Qt::Key_Return:
// Propagate the enter if you couldn't edit the item and there are no
// current editors (if there are editors, the event was most likely propagated from it).
- if (!edit(currentIndex(), EditKeyPressed, event) && d->editors.isEmpty())
+ if (!edit(currentIndex(), EditKeyPressed, event) && d->editorIndexHash.isEmpty())
event->ignore();
break;
#else
@@ -2518,7 +2521,7 @@ bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEve
if (!d->isIndexValid(index))
return false;
- if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(0) : d->editorForIndex(index).editor.data())) {
+ if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(0) : d->editorForIndex(index).widget.data())) {
if (w->focusPolicy() == Qt::NoFocus)
return false;
w->setFocus();
@@ -2578,15 +2581,15 @@ void QAbstractItemView::updateEditorData()
void QAbstractItemView::updateEditorGeometries()
{
Q_D(QAbstractItemView);
- if(d->editors.isEmpty())
+ if(d->editorIndexHash.isEmpty())
return;
QStyleOptionViewItemV4 option = d->viewOptionsV4();
- QList<QEditorInfo>::iterator it = d->editors.begin();
+ QEditorIndexHash::iterator it = d->editorIndexHash.begin();
QWidgetList editorsToRelease;
QWidgetList editorsToHide;
- while (it != d->editors.end()) {
- QModelIndex index = it->index;
- QWidget *editor = it->editor;
+ while (it != d->editorIndexHash.end()) {
+ QModelIndex index = it.value();
+ QWidget *editor = it.key();
if (index.isValid() && editor) {
option.rect = visualRect(index);
if (option.rect.isValid()) {
@@ -2599,13 +2602,14 @@ void QAbstractItemView::updateEditorGeometries()
}
++it;
} else {
- it = d->editors.erase(it);
+ d->indexEditorHash.remove(it.value());
+ it = d->editorIndexHash.erase(it);
editorsToRelease << editor;
}
}
//we hide and release the editor outside of the loop because it might change the focus and try
- //to change the d->editors list.
+ //to change the editors hashes.
for (int i = 0; i < editorsToHide.count(); ++i) {
editorsToHide.at(i)->hide();
}
@@ -2945,7 +2949,7 @@ int QAbstractItemView::sizeHintForRow(int row) const
{
Q_D(const QAbstractItemView);
- if (row < 0 || row >= d->model->rowCount() || !model())
+ if (row < 0 || row >= d->model->rowCount(d->root))
return -1;
ensurePolished();
@@ -2956,8 +2960,8 @@ int QAbstractItemView::sizeHintForRow(int row) const
QModelIndex index;
for (int c = 0; c < colCount; ++c) {
index = d->model->index(row, c, d->root);
- if (QWidget *editor = d->editorForIndex(index).editor)
- height = qMax(height, editor->size().height());
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
+ height = qMax(height, editor->height());
int hint = d->delegateForIndex(index)->sizeHint(option, index).height();
height = qMax(height, hint);
}
@@ -2976,7 +2980,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
{
Q_D(const QAbstractItemView);
- if (column < 0 || column >= d->model->columnCount() || !model())
+ if (column < 0 || column >= d->model->columnCount(d->root))
return -1;
ensurePolished();
@@ -2987,7 +2991,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
QModelIndex index;
for (int r = 0; r < rows; ++r) {
index = d->model->index(r, column, d->root);
- if (QWidget *editor = d->editorForIndex(index).editor)
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
width = qMax(width, editor->sizeHint().width());
int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
width = qMax(width, hint);
@@ -3023,8 +3027,7 @@ void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
{
Q_D(QAbstractItemView);
- QWidget *editor = d->editorForIndex(index).editor;
- if (editor) {
+ if (QWidget *editor = d->editorForIndex(index).widget.data()) {
if (index == selectionModel()->currentIndex())
closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
d->persistent.remove(editor);
@@ -3088,9 +3091,11 @@ void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget
QWidget* QAbstractItemView::indexWidget(const QModelIndex &index) const
{
Q_D(const QAbstractItemView);
- if (!d->isIndexValid(index))
- return 0;
- return d->editorForIndex(index).editor;
+ if (d->isIndexValid(index))
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
+ return editor;
+
+ return 0;
}
/*!
@@ -3152,12 +3157,12 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
// Single item changed
Q_D(QAbstractItemView);
if (topLeft == bottomRight && topLeft.isValid()) {
- const QEditorInfo editorInfo = d->editorForIndex(topLeft);
+ const QEditorInfo &editorInfo = d->editorForIndex(topLeft);
//we don't update the edit data if it is static
- if (!editorInfo.isStatic && editorInfo.editor) {
+ if (!editorInfo.isStatic && editorInfo.widget) {
QAbstractItemDelegate *delegate = d->delegateForIndex(topLeft);
if (delegate) {
- delegate->setEditorData(editorInfo.editor, topLeft);
+ delegate->setEditorData(editorInfo.widget.data(), topLeft);
}
}
if (isVisible() && !d->delayedPendingLayout) {
@@ -3231,12 +3236,17 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
}
// Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
- for (int i = d->editors.size() - 1; i >= 0; --i) {
- const QModelIndex index = d->editors.at(i).index;
- QWidget *editor = d->editors.at(i).editor;
+ QEditorIndexHash::iterator i = d->editorIndexHash.begin();
+ while (i != d->editorIndexHash.end()) {
+ const QModelIndex index = i.value();
if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
- d->editors.removeAt(i);
- d->releaseEditor(editor);
+ QWidget *editor = i.key();
+ QEditorInfo info = d->indexEditorHash.take(index);
+ i = d->editorIndexHash.erase(i);
+ if (info.widget)
+ d->releaseEditor(editor);
+ } else {
+ ++i;
}
}
}
@@ -3293,17 +3303,20 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par
}
// Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
- QList<QEditorInfo>::iterator it = editors.begin();
- while (it != editors.end()) {
- QModelIndex index = it->index;
+ QEditorIndexHash::iterator it = editorIndexHash.begin();
+ while (it != editorIndexHash.end()) {
+ QModelIndex index = it.value();
if (index.column() <= start && index.column() >= end && model->parent(index) == parent) {
- QWidget *editor = it->editor;
- it = editors.erase(it);
- releaseEditor(editor);
+ QWidget *editor = it.key();
+ QEditorInfo info = indexEditorHash.take(it.value());
+ it = editorIndexHash.erase(it);
+ if (info.widget)
+ releaseEditor(editor);
} else {
++it;
}
}
+
}
/*!
@@ -3385,7 +3398,7 @@ void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelI
if (previous.isValid()) {
QModelIndex buddy = d->model->buddy(previous);
- QWidget *editor = d->editorForIndex(buddy).editor;
+ QWidget *editor = d->editorForIndex(buddy).widget.data();
if (editor && !d->persistent.contains(editor)) {
commitData(editor);
if (current.row() != previous.row())
@@ -3911,7 +3924,7 @@ QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
{
Q_Q(QAbstractItemView);
- QWidget *w = editorForIndex(index).editor;
+ QWidget *w = editorForIndex(index).widget.data();
if (!w) {
QAbstractItemDelegate *delegate = delegateForIndex(index);
if (!delegate)
@@ -3942,6 +3955,7 @@ QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
#endif
}
}
+
return w;
}
@@ -3950,11 +3964,11 @@ void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QMo
// we are counting on having relatively few editors
const bool checkIndexes = tl.isValid() && br.isValid();
const QModelIndex parent = tl.parent();
- QList<QEditorInfo>::const_iterator it = editors.constBegin();
- for (; it != editors.constEnd(); ++it) {
- QWidget *editor = it->editor;
- const QModelIndex index = it->index;
- if (it->isStatic || editor == 0 || !index.isValid() ||
+ QIndexEditorHash::const_iterator it = indexEditorHash.constBegin();
+ for (; it != indexEditorHash.constEnd(); ++it) {
+ QWidget *editor = it.value().widget.data();
+ const QModelIndex index = it.key();
+ if (it.value().isStatic || !editor || !index.isValid() ||
(checkIndexes
&& (index.row() < tl.row() || index.row() > br.row()
|| index.column() < tl.column() || index.column() > br.column()
@@ -4027,41 +4041,40 @@ void QAbstractItemViewPrivate::checkPersistentEditorFocus()
}
-QEditorInfo QAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const
+const QEditorInfo & QAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const
{
- QList<QEditorInfo>::const_iterator it = editors.constBegin();
- for (; it != editors.constEnd(); ++it) {
- if (it->index == index)
- return *it;
- }
+ static QEditorInfo nullInfo;
- return QEditorInfo();
+ QIndexEditorHash::const_iterator it = indexEditorHash.find(index);
+ if (it == indexEditorHash.end())
+ return nullInfo;
+
+ return it.value();
}
QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
{
- QList<QEditorInfo>::const_iterator it = editors.constBegin();
- for (; it != editors.constEnd(); ++it) {
- if (it->editor == editor)
- return it->index;
- }
- return QModelIndex();
+ QEditorIndexHash::const_iterator it = editorIndexHash.find(editor);
+ if (it == editorIndexHash.end())
+ return QModelIndex();
+
+ return it.value();
}
void QAbstractItemViewPrivate::removeEditor(QWidget *editor)
{
- QList<QEditorInfo>::iterator it = editors.begin();
- for (; it != editors.end(); ) {
- if (it->editor == editor)
- it = editors.erase(it);
- else
- ++it;
+ QEditorIndexHash::iterator it = editorIndexHash.find(editor);
+ if (it != editorIndexHash.end())
+ {
+ indexEditorHash.remove(it.value());
+ editorIndexHash.erase(it);
}
}
void QAbstractItemViewPrivate::addEditor(const QModelIndex &index, QWidget *editor, bool isStatic)
{
- editors.append(QEditorInfo(index, editor, isStatic));
+ editorIndexHash.insert(editor, index);
+ indexEditorHash.insert(index, QEditorInfo(editor, isStatic));
}
bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEvent *event) const
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index fce74f3f54..03b413a399 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -70,22 +70,18 @@
QT_BEGIN_NAMESPACE
-struct QEditorInfo
-{
- QEditorInfo() : isStatic(false)
- {
- }
-
- QEditorInfo(const QPersistentModelIndex &i, QWidget *e, bool b) : index(i), editor(e), isStatic(b)
- {
- }
-
- QPersistentModelIndex index;
- QPointer<QWidget> editor;
- bool isStatic; //true when called from setIndexWidget
+struct QEditorInfo {
+ QEditorInfo(QWidget *e, bool s): widget(QWeakPointer<QWidget>(e)), isStatic(s) {}
+ QEditorInfo(): isStatic(false) {}
+ QWeakPointer<QWidget> widget;
+ bool isStatic;
};
+// Fast associativity between Persistent editors and indices.
+typedef QHash<QWidget *, QPersistentModelIndex> QEditorIndexHash;
+typedef QHash<QPersistentModelIndex, QEditorInfo> QIndexEditorHash;
+
typedef QPair<QRect, QModelIndex> QItemViewPaintPair;
typedef QList<QItemViewPaintPair> QItemViewPaintPairs;
@@ -135,8 +131,9 @@ public:
}
void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;}
-
- bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
+#ifndef QT_NO_DRAGANDDROP
+ virtual bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
+#endif
bool droppingOnItself(QDropEvent *event, const QModelIndex &index);
QWidget *editor(const QModelIndex &index, const QStyleOptionViewItem &options);
@@ -247,9 +244,9 @@ public:
: q->horizontalOffset(), q->verticalOffset());
}
- QEditorInfo editorForIndex(const QModelIndex &index) const;
+ const QEditorInfo &editorForIndex(const QModelIndex &index) const;
inline bool hasEditor(const QModelIndex &index) const {
- return editorForIndex(index).editor != 0;
+ return indexEditorHash.find(index) != indexEditorHash.constEnd();
}
QModelIndex indexForEditor(QWidget *editor) const;
@@ -352,7 +349,8 @@ public:
QAbstractItemView::SelectionMode selectionMode;
QAbstractItemView::SelectionBehavior selectionBehavior;
- QList<QEditorInfo> editors;
+ QEditorIndexHash editorIndexHash;
+ QIndexEditorHash indexEditorHash;
QSet<QWidget*> persistent;
QWidget *currentlyCommittingEditor;
@@ -367,6 +365,7 @@ public:
bool viewportEnteredNeeded;
QAbstractItemView::State state;
+ QAbstractItemView::State stateBeforeAnimation;
QAbstractItemView::EditTriggers editTriggers;
QAbstractItemView::EditTrigger lastTrigger;
diff --git a/src/gui/itemviews/qabstractproxymodel.cpp b/src/gui/itemviews/qabstractproxymodel.cpp
index 1c600e202f..51dfa7a86e 100644
--- a/src/gui/itemviews/qabstractproxymodel.cpp
+++ b/src/gui/itemviews/qabstractproxymodel.cpp
@@ -45,6 +45,9 @@
#include "qitemselectionmodel.h"
#include <private/qabstractproxymodel_p.h>
+#include <QtCore/QSize>
+#include <QtCore/QStringList>
+
QT_BEGIN_NAMESPACE
@@ -270,6 +273,15 @@ bool QAbstractProxyModel::setData(const QModelIndex &index, const QVariant &valu
/*!
\reimp
*/
+bool QAbstractProxyModel::setItemData(const QModelIndex &index, const QMap< int, QVariant >& roles)
+{
+ Q_D(QAbstractProxyModel);
+ return d->model->setItemData(mapToSource(index), roles);
+}
+
+/*!
+ \reimp
+ */
bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
Q_D(QAbstractProxyModel);
@@ -284,6 +296,90 @@ bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation
return d->model->setHeaderData(sourceSection, orientation, value, role);
}
+/*!
+ \reimp
+ */
+QModelIndex QAbstractProxyModel::buddy(const QModelIndex &index) const
+{
+ Q_D(const QAbstractProxyModel);
+ return mapFromSource(d->model->buddy(mapToSource(index)));
+}
+
+/*!
+ \reimp
+ */
+bool QAbstractProxyModel::canFetchMore(const QModelIndex &parent) const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->canFetchMore(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+void QAbstractProxyModel::fetchMore(const QModelIndex &parent)
+{
+ Q_D(QAbstractProxyModel);
+ d->model->fetchMore(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+void QAbstractProxyModel::sort(int column, Qt::SortOrder order)
+{
+ Q_D(QAbstractProxyModel);
+ d->model->sort(column, order);
+}
+
+/*!
+ \reimp
+ */
+QSize QAbstractProxyModel::span(const QModelIndex &index) const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->span(mapToSource(index));
+}
+
+/*!
+ \reimp
+ */
+bool QAbstractProxyModel::hasChildren(const QModelIndex &parent) const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->hasChildren(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const
+{
+ Q_D(const QAbstractProxyModel);
+ QModelIndexList list;
+ foreach(const QModelIndex &index, indexes)
+ list << mapToSource(index);
+ return d->model->mimeData(indexes);
+}
+
+/*!
+ \reimp
+ */
+QStringList QAbstractProxyModel::mimeTypes() const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->mimeTypes();
+}
+
+/*!
+ \reimp
+ */
+Qt::DropActions QAbstractProxyModel::supportedDropActions() const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->supportedDropActions();
+}
+
QT_END_NAMESPACE
#include "moc_qabstractproxymodel.cpp"
diff --git a/src/gui/itemviews/qabstractproxymodel.h b/src/gui/itemviews/qabstractproxymodel.h
index c6bb9852d3..a5a1168d61 100644
--- a/src/gui/itemviews/qabstractproxymodel.h
+++ b/src/gui/itemviews/qabstractproxymodel.h
@@ -81,8 +81,20 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ bool setItemData(const QModelIndex& index, const QMap<int, QVariant> &roles);
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+ QModelIndex buddy(const QModelIndex &index) const;
+ bool canFetchMore(const QModelIndex &parent) const;
+ void fetchMore(const QModelIndex &parent);
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+ QSize span(const QModelIndex &index) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ QMimeData* mimeData(const QModelIndexList &indexes) const;
+ QStringList mimeTypes() const;
+ Qt::DropActions supportedDropActions() const;
+
protected:
QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent);
diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp
index 67854a3f9e..7eb3ddcb7a 100644
--- a/src/gui/itemviews/qheaderview.cpp
+++ b/src/gui/itemviews/qheaderview.cpp
@@ -2105,7 +2105,7 @@ void QHeaderView::paintEvent(QPaintEvent *e)
QVariant variant = d->model->headerData(logical, d->orientation,
Qt::FontRole);
- if (variant.isValid() && qVariantCanConvert<QFont>(variant)) {
+ if (variant.isValid() && variant.canConvert<QFont>()) {
QFont sectionFont = qvariant_cast<QFont>(variant);
painter.setFont(sectionFont);
}
@@ -2485,13 +2485,13 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical
opt.icon = qvariant_cast<QPixmap>(variant);
QVariant foregroundBrush = d->model->headerData(logicalIndex, d->orientation,
Qt::ForegroundRole);
- if (qVariantCanConvert<QBrush>(foregroundBrush))
+ if (foregroundBrush.canConvert<QBrush>())
opt.palette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(foregroundBrush));
QPointF oldBO = painter->brushOrigin();
QVariant backgroundBrush = d->model->headerData(logicalIndex, d->orientation,
Qt::BackgroundRole);
- if (qVariantCanConvert<QBrush>(backgroundBrush)) {
+ if (backgroundBrush.canConvert<QBrush>()) {
opt.palette.setBrush(QPalette::Button, qvariant_cast<QBrush>(backgroundBrush));
opt.palette.setBrush(QPalette::Window, qvariant_cast<QBrush>(backgroundBrush));
painter->setBrushOrigin(opt.rect.topLeft());
@@ -2552,7 +2552,7 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const
QVariant var = d->model->headerData(logicalIndex, d->orientation,
Qt::FontRole);
QFont fnt;
- if (var.isValid() && qVariantCanConvert<QFont>(var))
+ if (var.isValid() && var.canConvert<QFont>())
fnt = qvariant_cast<QFont>(var);
else
fnt = font();
diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp
index 9bbfc23c1a..6556a3e0cf 100644
--- a/src/gui/itemviews/qitemdelegate.cpp
+++ b/src/gui/itemviews/qitemdelegate.cpp
@@ -850,7 +850,7 @@ void QItemDelegate::drawBackground(QPainter *painter,
painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
} else {
QVariant value = index.data(Qt::BackgroundRole);
- if (qVariantCanConvert<QBrush>(value)) {
+ if (value.canConvert<QBrush>()) {
QPointF oldBO = painter->brushOrigin();
painter->setBrushOrigin(option.rect.topLeft());
painter->fillRect(option.rect, qvariant_cast<QBrush>(value));
@@ -1278,7 +1278,8 @@ bool QItemDelegate::editorEvent(QEvent *event,
// make sure that we have the right event type
if ((event->type() == QEvent::MouseButtonRelease)
- || (event->type() == QEvent::MouseButtonDblClick)) {
+ || (event->type() == QEvent::MouseButtonDblClick)
+ || (event->type() == QEvent::MouseButtonPress)) {
QRect checkRect = check(option, option.rect, Qt::Checked);
QRect emptyRect;
doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
@@ -1287,7 +1288,8 @@ bool QItemDelegate::editorEvent(QEvent *event,
return false;
// eat the double click events inside the check rect
- if (event->type() == QEvent::MouseButtonDblClick)
+ if ((event->type() == QEvent::MouseButtonPress)
+ || (event->type() == QEvent::MouseButtonDblClick))
return true;
} else if (event->type() == QEvent::KeyPress) {
@@ -1326,7 +1328,7 @@ QStyleOptionViewItem QItemDelegate::setOptions(const QModelIndex &index,
// set foreground brush
value = index.data(Qt::ForegroundRole);
- if (qVariantCanConvert<QBrush>(value))
+ if (value.canConvert<QBrush>())
opt.palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
return opt;
diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp
index f848321b75..7156b8713d 100644
--- a/src/gui/itemviews/qitemselectionmodel.cpp
+++ b/src/gui/itemviews/qitemselectionmodel.cpp
@@ -212,6 +212,7 @@ bool QItemSelectionRange::intersects(const QItemSelectionRange &other) const
{
return (isValid() && other.isValid()
&& parent() == other.parent()
+ && model() == other.model()
&& ((top() <= other.top() && bottom() >= other.top())
|| (top() >= other.top() && top() <= other.bottom()))
&& ((left() <= other.left() && right() >= other.left())
@@ -508,7 +509,7 @@ void QItemSelection::merge(const QItemSelection &other, QItemSelectionModel::Sel
void QItemSelection::split(const QItemSelectionRange &range,
const QItemSelectionRange &other, QItemSelection *result)
{
- if (range.parent() != other.parent())
+ if (range.parent() != other.parent() || range.model() != other.model())
return;
QModelIndex parent = other.parent();
@@ -634,6 +635,7 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
}
QItemSelection deselected;
+ QItemSelection newParts;
QItemSelection::iterator it = ranges.begin();
while (it != ranges.end()) {
if (it->topLeft().parent() != parent) { // Check parents until reaching root or contained in range
@@ -659,13 +661,20 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), it->bottomRight()));
*it = QItemSelectionRange(it->topLeft(), model->index(start - 1, it->right(), it->parent()));
++it;
- } else {
- if (it->top() < start && end < it->bottom()) // Middle intersection (do nothing)
- deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()),
- model->index(end, it->left(), it->parent())));
+ } else if (it->top() < start && end < it->bottom()) { // Middle intersection
+ // If the parent contains (1, 2, 3, 4, 5, 6, 7, 8) and [3, 4, 5, 6] is selected,
+ // and [4, 5] is removed, we need to split [3, 4, 5, 6] into [3], [4, 5] and [6].
+ // [4, 5] is appended to deselected, and [3] and [6] remain part of the selection
+ // in ranges.
+ const QItemSelectionRange removedRange(model->index(start, it->right(), it->parent()),
+ model->index(end, it->left(), it->parent()));
+ deselected.append(removedRange);
+ QItemSelection::split(*it, removedRange, &newParts);
+ it = ranges.erase(it);
+ } else
++it;
- }
}
+ ranges.append(newParts);
if (!deselected.isEmpty())
emit q->selectionChanged(QItemSelection(), deselected);
diff --git a/src/gui/itemviews/qitemselectionmodel.h b/src/gui/itemviews/qitemselectionmodel.h
index 436514fc6a..e2bd06b4b4 100644
--- a/src/gui/itemviews/qitemselectionmodel.h
+++ b/src/gui/itemviews/qitemselectionmodel.h
@@ -101,6 +101,30 @@ public:
{ return (tl == other.tl && br == other.br); }
inline bool operator!=(const QItemSelectionRange &other) const
{ return !operator==(other); }
+ inline bool operator<(const QItemSelectionRange &other) const
+ {
+ // Comparing parents will compare the models, but if two equivalent ranges
+ // in two different models have invalid parents, they would appear the same
+ if (other.tl.model() == tl.model()) {
+ // parent has to be calculated, so we only do so once.
+ const QModelIndex topLeftParent = tl.parent();
+ const QModelIndex otherTopLeftParent = other.tl.parent();
+ if (topLeftParent == otherTopLeftParent) {
+ if (other.tl.row() == tl.row()) {
+ if (other.tl.column() == tl.column()) {
+ if (other.br.row() == br.row()) {
+ return br.column() < other.br.column();
+ }
+ return br.row() < other.br.row();
+ }
+ return tl.column() < other.tl.column();
+ }
+ return tl.row() < other.tl.row();
+ }
+ return topLeftParent < otherTopLeftParent;
+ }
+ return tl.model() < other.tl.model();
+ }
inline bool isValid() const
{
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 76d76426dd..ce1f0e53e7 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -756,10 +756,13 @@ void QListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e
// if the parent is above d->root in the tree, nothing will happen
QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
if (parent == d->root) {
- for (int i = d->hiddenRows.count() - 1; i >= 0; --i) {
- int hiddenRow = d->hiddenRows.at(i).row();
+ QSet<QPersistentModelIndex>::iterator it = d->hiddenRows.begin();
+ while (it != d->hiddenRows.end()) {
+ int hiddenRow = it->row();
if (hiddenRow >= start && hiddenRow <= end) {
- d->hiddenRows.remove(i);
+ it = d->hiddenRows.erase(it);
+ } else {
+ ++it;
}
}
}
@@ -1033,16 +1036,7 @@ void QListView::paintEvent(QPaintEvent *e)
previousRow = row;
}
- if (const QWidget *widget = d->editorForIndex(*it).editor) {
- QRegion itemGeometry(option.rect);
- QRegion widgetGeometry(widget->geometry());
- painter.save();
- painter.setClipRegion(itemGeometry.subtracted(widgetGeometry));
- d->delegateForIndex(*it)->paint(&painter, option, *it);
- painter.restore();
- } else {
- d->delegateForIndex(*it)->paint(&painter, option, *it);
- }
+ d->delegateForIndex(*it)->paint(&painter, option, *it);
}
#ifndef QT_NO_DRAGANDDROP
@@ -1833,6 +1827,14 @@ QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint
else
return QAbstractItemViewPrivate::position(pos, rect, idx);
}
+
+bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
+{
+ if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
+ return static_cast<QListModeViewBase *>(commonListView)->dropOn(event, dropRow, dropCol, dropIndex);
+ else
+ return QAbstractItemViewPrivate::dropOn(event, dropRow, dropCol, dropIndex);
+}
#endif
/*
@@ -1841,12 +1843,12 @@ QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint
void QCommonListViewBase::appendHiddenRow(int row)
{
- dd->hiddenRows.append(dd->model->index(row, 0, qq->rootIndex()));
+ dd->hiddenRows.insert(dd->model->index(row, 0, qq->rootIndex()));
}
void QCommonListViewBase::removeHiddenRow(int row)
{
- dd->hiddenRows.remove(dd->hiddenRows.indexOf(dd->model->index(row, 0, qq->rootIndex())));
+ dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex()));
}
void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
@@ -1960,7 +1962,13 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
// ignore by default
event->ignore();
- QModelIndex index = qq->indexAt(event->pos());
+ // can't use indexAt, doesn't account for spacing.
+ QPoint p = event->pos();
+ QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
+ rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
+ const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
+ QModelIndex index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
dd->hover = index;
if (!dd->droppingOnItself(event, index)
&& dd->canDecode(event)) {
@@ -1968,10 +1976,11 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
if (index.isValid() && dd->showDropIndicator) {
QRect rect = qq->visualRect(index);
dd->dropIndicatorPosition = position(event->pos(), rect, index);
+ // if spacing, should try to draw between items, not just next to item.
switch (dd->dropIndicatorPosition) {
case QAbstractItemView::AboveItem:
if (dd->isIndexDropEnabled(index.parent())) {
- dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height());
+ dd->dropIndicatorRect = QRect(rect.left()-dd->spacing(), rect.top(), 0, rect.height());
event->accept();
} else {
dd->dropIndicatorRect = QRect();
@@ -1979,7 +1988,7 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
break;
case QAbstractItemView::BelowItem:
if (dd->isIndexDropEnabled(index.parent())) {
- dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height());
+ dd->dropIndicatorRect = QRect(rect.right()+dd->spacing(), rect.top(), 0, rect.height());
event->accept();
} else {
dd->dropIndicatorRect = QRect();
@@ -2014,6 +2023,68 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
qq->startAutoScroll();
}
+/*!
+ If the event hasn't already been accepted, determines the index to drop on.
+
+ if (row == -1 && col == -1)
+ // append to this drop index
+ else
+ // place at row, col in drop index
+
+ If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop.
+ \internal
+ */
+bool QListModeViewBase::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
+{
+ if (event->isAccepted())
+ return false;
+
+ QModelIndex index;
+ if (dd->viewport->rect().contains(event->pos())) {
+ // can't use indexAt, doesn't account for spacing.
+ QPoint p = event->pos();
+ QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
+ rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
+ const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
+ index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
+ if (!index.isValid())
+ index = dd->root;
+ }
+
+ // If we are allowed to do the drop
+ if (dd->model->supportedDropActions() & event->dropAction()) {
+ int row = -1;
+ int col = -1;
+ if (index != dd->root) {
+ dd->dropIndicatorPosition = position(event->pos(), qq->visualRect(index), index);
+ switch (dd->dropIndicatorPosition) {
+ case QAbstractItemView::AboveItem:
+ row = index.row();
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::BelowItem:
+ row = index.row() + 1;
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::OnItem:
+ case QAbstractItemView::OnViewport:
+ break;
+ }
+ } else {
+ dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
+ }
+ *dropIndex = index;
+ *dropRow = row;
+ *dropCol = col;
+ if (!dd->droppingOnItself(event, index))
+ return true;
+ }
+ return false;
+}
+
#endif //QT_NO_DRAGANDDROP
void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
@@ -2107,7 +2178,7 @@ int QListModeViewBase::verticalOffset() const
int value = verticalScrollBar()->value();
if (value >= segmentPositions.count())
return 0;
- return segmentPositions.at(value);
+ return segmentPositions.at(value) - spacing();
}
} else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
int value = verticalScrollBar()->value();
@@ -2155,14 +2226,14 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
if (horizontal && flow() == QListView::TopToBottom && dx != 0) {
int currentValue = qBound(0, horizontalValue, max);
int previousValue = qBound(0, currentValue + dx, max);
- int currentCoordinate = segmentPositions.at(currentValue);
- int previousCoordinate = segmentPositions.at(previousValue);
+ int currentCoordinate = segmentPositions.at(currentValue) - spacing();
+ int previousCoordinate = segmentPositions.at(previousValue) - spacing();
dx = previousCoordinate - currentCoordinate;
} else if (vertical && flow() == QListView::LeftToRight && dy != 0) {
int currentValue = qBound(0, verticalValue, max);
int previousValue = qBound(0, currentValue + dy, max);
- int currentCoordinate = segmentPositions.at(currentValue);
- int previousCoordinate = segmentPositions.at(previousValue);
+ int currentCoordinate = segmentPositions.at(currentValue) - spacing();
+ int previousCoordinate = segmentPositions.at(previousValue) - spacing();
dy = previousCoordinate - currentCoordinate;
}
} else {
@@ -2330,6 +2401,8 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
segmentExtents.append(flowPosition);
flowPosition = info.spacing + segStartPosition;
segPosition += deltaSegPosition;
+ if (info.wrap)
+ segPosition += info.spacing;
segmentPositions.append(segPosition);
segmentStartRows.append(row);
deltaSegPosition = 0;
diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h
index bf7657b3c0..1b71131446 100644
--- a/src/gui/itemviews/qlistview_p.h
+++ b/src/gui/itemviews/qlistview_p.h
@@ -237,6 +237,7 @@ public:
// WARNING: Plenty of duplicated code from QAbstractItemView{,Private}.
QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
void dragMoveEvent(QDragMoveEvent *e);
+ bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
#endif
private:
@@ -364,6 +365,7 @@ public:
#ifndef QT_NO_DRAGANDDROP
virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
+ bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
#endif
inline void setGridSize(const QSize &size) { grid = size; }
@@ -376,7 +378,10 @@ public:
inline bool isSelectionRectVisible() const { return showElasticBand; }
inline QModelIndex modelIndex(int row) const { return model->index(row, column, root); }
- inline bool isHidden(int row) const { return hiddenRows.contains(model->index(row, 0, root)); }
+ inline bool isHidden(int row) const {
+ QModelIndex idx = model->index(row, 0, root);
+ return isPersistent(idx) && hiddenRows.contains(idx);
+ }
inline bool isHiddenOrDisabled(int row) const { return isHidden(row) || !isIndexEnabled(modelIndex(row)); }
inline void removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const {
@@ -430,7 +435,7 @@ public:
QBasicTimer batchLayoutTimer;
// used for hidden items
- QVector<QPersistentModelIndex> hiddenRows;
+ QSet<QPersistentModelIndex> hiddenRows;
int column;
bool uniformItemSizes;
diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp
index 880f8ab67c..9ccfb76252 100644
--- a/src/gui/itemviews/qstyleditemdelegate.cpp
+++ b/src/gui/itemviews/qstyleditemdelegate.cpp
@@ -326,7 +326,7 @@ void QStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option,
option->displayAlignment = Qt::Alignment(value.toInt());
value = index.data(Qt::ForegroundRole);
- if (qVariantCanConvert<QBrush>(value))
+ if (value.canConvert<QBrush>())
option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
if (QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>(option)) {
@@ -727,7 +727,8 @@ bool QStyledItemDelegate::editorEvent(QEvent *event,
// make sure that we have the right event type
if ((event->type() == QEvent::MouseButtonRelease)
- || (event->type() == QEvent::MouseButtonDblClick)) {
+ || (event->type() == QEvent::MouseButtonDblClick)
+ || (event->type() == QEvent::MouseButtonPress)) {
QStyleOptionViewItemV4 viewOpt(option);
initStyleOption(&viewOpt, index);
QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &viewOpt, widget);
@@ -735,8 +736,8 @@ bool QStyledItemDelegate::editorEvent(QEvent *event,
if (me->button() != Qt::LeftButton || !checkRect.contains(me->pos()))
return false;
- // eat the double click events inside the check rect
- if (event->type() == QEvent::MouseButtonDblClick)
+ if ((event->type() == QEvent::MouseButtonPress)
+ || (event->type() == QEvent::MouseButtonDblClick))
return true;
} else if (event->type() == QEvent::KeyPress) {
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 4492e53fcc..d8fef5529f 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -926,14 +926,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV4
q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q);
- if (const QWidget *widget = editorForIndex(index).editor) {
- painter->save();
- painter->setClipRect(widget->geometry());
- q->itemDelegate(index)->paint(painter, opt, index);
- painter->restore();
- } else {
- q->itemDelegate(index)->paint(painter, opt, index);
- }
+ q->itemDelegate(index)->paint(painter, opt, index);
}
/*!
@@ -2166,7 +2159,7 @@ int QTableView::sizeHintForRow(int row) const
option.rect.setWidth(columnWidth(index.column()));
}
- QWidget *editor = d->editorForIndex(index).editor;
+ QWidget *editor = d->editorForIndex(index).widget.data();
if (editor && d->persistent.contains(editor)) {
hint = qMax(hint, editor->sizeHint().height());
int min = editor->minimumSize().height();
@@ -2219,7 +2212,7 @@ int QTableView::sizeHintForColumn(int column) const
continue;
index = d->model->index(logicalRow, column, d->root);
- QWidget *editor = d->editorForIndex(index).editor;
+ QWidget *editor = d->editorForIndex(index).widget.data();
if (editor && d->persistent.contains(editor)) {
hint = qMax(hint, editor->sizeHint().width());
int min = editor->minimumSize().width();
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index b797776e20..e3939026d4 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -1493,7 +1493,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
// when the row contains an index widget which has focus,
// we want to paint the entire row as active
bool indexWidgetHasFocus = false;
- if ((current.row() == index.row()) && !d->editors.isEmpty()) {
+ if ((current.row() == index.row()) && !d->editorIndexHash.isEmpty()) {
const int r = index.row();
QWidget *fw = QApplication::focusWidget();
for (int c = 0; c < header->count(); ++c) {
@@ -1669,14 +1669,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
opt.state = oldState;
}
- if (const QWidget *widget = d->editorForIndex(modelIndex).editor) {
- painter->save();
- painter->setClipRect(widget->geometry());
- d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
- painter->restore();
- } else {
- d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
- }
+ d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
}
if (currentRowHasFocus) {
@@ -2395,7 +2388,7 @@ void QTreeView::scrollContentsBy(int dx, int dy)
int viewCount = d->viewport->height() / itemHeight;
int maxDeltaY = qMin(d->viewItems.count(), viewCount);
// no need to do a lot of work if we are going to redraw the whole thing anyway
- if (qAbs(dy) > qAbs(maxDeltaY) && d->editors.isEmpty()) {
+ if (qAbs(dy) > qAbs(maxDeltaY) && d->editorIndexHash.isEmpty()) {
verticalScrollBar()->update();
d->viewport->update();
return;
@@ -2469,11 +2462,9 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
}
const int parentItem = d->viewIndex(parent);
- if (((parentItem != -1) && d->viewItems.at(parentItem).expanded && updatesEnabled())
+ if (((parentItem != -1) && d->viewItems.at(parentItem).expanded)
|| (parent == d->root)) {
d->doDelayedItemsLayout();
- } else if ((parentItem != -1) && d->viewItems.at(parentItem).expanded) {
- d->doDelayedItemsLayout();
} else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) {
// the parent just went from 0 children to more. update to re-paint the decoration
d->viewItems[parentItem].hasChildren = true;
@@ -2727,7 +2718,7 @@ int QTreeView::sizeHintForColumn(int column) const
continue; // we have no good size hint
QModelIndex index = viewItems.at(i).index;
index = index.sibling(index.row(), column);
- QWidget *editor = d->editorForIndex(index).editor;
+ QWidget *editor = d->editorForIndex(index).widget.data();
if (editor && d->persistent.contains(editor)) {
w = qMax(w, editor->sizeHint().width());
int min = editor->minimumSize().width();
@@ -2791,7 +2782,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
continue;
QModelIndex idx = d->model->index(index.row(), logicalColumn, parent);
if (idx.isValid()) {
- QWidget *editor = d->editorForIndex(idx).editor;
+ QWidget *editor = d->editorForIndex(idx).widget.data();
if (editor && d->persistent.contains(editor)) {
height = qMax(height, editor->sizeHint().height());
int min = editor->minimumSize().height();
@@ -2870,13 +2861,13 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
if (emitSignal && animationsEnabled)
prepareAnimatedOperation(item, QVariantAnimation::Forward);
#endif //QT_NO_ANIMATION
- QAbstractItemView::State oldState = state;
+ stateBeforeAnimation = state;
q->setState(QAbstractItemView::ExpandingState);
const QModelIndex index = viewItems.at(item).index;
storeExpanded(index);
viewItems[item].expanded = true;
layout(item);
- q->setState(oldState);
+ q->setState(stateBeforeAnimation);
if (model->canFetchMore(index))
model->fetchMore(index);
@@ -2945,7 +2936,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal)
prepareAnimatedOperation(item, QVariantAnimation::Backward);
#endif //QT_NO_ANIMATION
- QAbstractItemView::State oldState = state;
+ stateBeforeAnimation = state;
q->setState(QAbstractItemView::CollapsingState);
expandedIndexes.erase(it);
viewItems[item].expanded = false;
@@ -2955,7 +2946,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal)
index = viewItems[index].parentItem;
}
removeViewItems(item + 1, total); // collapse
- q->setState(oldState);
+ q->setState(stateBeforeAnimation);
if (emitSignal) {
emit q->collapsed(modelIndex);
@@ -3040,9 +3031,9 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
//and now let's render the editors the editors
QStyleOptionViewItemV4 option = viewOptionsV4();
- for (QList<QEditorInfo>::const_iterator it = editors.constBegin(); it != editors.constEnd(); ++it) {
- QWidget *editor = it->editor;
- QModelIndex index = it->index;
+ for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
+ QWidget *editor = it.key();
+ const QModelIndex &index = it.value();
option.rect = q->visualRect(index);
if (option.rect.isValid()) {
@@ -3066,7 +3057,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
void QTreeViewPrivate::_q_endAnimatedOperation()
{
Q_Q(QTreeView);
- q->setState(QAbstractItemView::NoState);
+ q->setState(stateBeforeAnimation);
q->updateGeometries();
viewport->update();
}
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index f9c84c1ebe..2629d7fa13 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -216,7 +216,8 @@ embedded {
qcocoaapplicationdelegate_mac_p.h \
qmacgesturerecognizer_mac_p.h \
qmultitouch_mac_p.h \
- qcocoasharedwindowmethods_mac_p.h
+ qcocoasharedwindowmethods_mac_p.h \
+ qcocoaintrospection_p.h
OBJECTIVE_SOURCES += \
kernel/qcursor_mac.mm \
@@ -236,7 +237,8 @@ embedded {
kernel/qeventdispatcher_mac.mm \
kernel/qcocoawindowcustomthemeframe_mac.mm \
kernel/qmacgesturerecognizer_mac.mm \
- kernel/qmultitouch_mac.mm
+ kernel/qmultitouch_mac.mm \
+ kernel/qcocoaintrospection_mac.mm
HEADERS += \
kernel/qt_cocoa_helpers_mac_p.h \
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 43d5772814..d97a57ef0f 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -153,8 +153,6 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT void qt_call_post_routines();
-int QApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0
-
QApplication::Type qt_appType=QApplication::Tty;
QApplicationPrivate *QApplicationPrivate::self = 0;
@@ -169,8 +167,8 @@ bool QApplicationPrivate::autoSipEnabled = false;
bool QApplicationPrivate::autoSipEnabled = true;
#endif
-QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type)
- : QCoreApplicationPrivate(argc, argv)
+QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags)
+ : QCoreApplicationPrivate(argc, argv, flags)
{
application_type = type;
qt_appType = type;
@@ -715,12 +713,12 @@ void QApplicationPrivate::process_cmdline()
*/
QApplication::QApplication(int &argc, char **argv)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
{ Q_D(QApplication); d->construct(); }
QApplication::QApplication(int &argc, char **argv, int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
-{ Q_D(QApplication); d->construct(); QApplicationPrivate::app_compile_version = _internal;}
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
+{ Q_D(QApplication); d->construct(); }
/*!
@@ -749,12 +747,12 @@ QApplication::QApplication(int &argc, char **argv, int _internal)
*/
QApplication::QApplication(int &argc, char **argv, bool GUIenabled )
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty))
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, 0x040000))
{ Q_D(QApplication); d->construct(); }
QApplication::QApplication(int &argc, char **argv, bool GUIenabled , int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty))
-{ Q_D(QApplication); d->construct(); QApplicationPrivate::app_compile_version = _internal;}
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, _internal))
+{ Q_D(QApplication); d->construct();}
@@ -772,12 +770,12 @@ QApplication::QApplication(int &argc, char **argv, bool GUIenabled , int _intern
\c -qws option).
*/
QApplication::QApplication(int &argc, char **argv, Type type)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, type))
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, type, 0x040000))
{ Q_D(QApplication); d->construct(); }
QApplication::QApplication(int &argc, char **argv, Type type , int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, type))
-{ Q_D(QApplication); d->construct(); QApplicationPrivate::app_compile_version = _internal;}
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, type, _internal))
+{ Q_D(QApplication); d->construct(); }
#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
static int qt_matchLibraryName(dl_phdr_info *info, size_t, void *data)
@@ -883,7 +881,7 @@ static char *aargv[] = { (char*)"unknown", 0 };
This function is only available on X11.
*/
QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
- : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient))
+ : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient, 0x040000))
{
if (! dpy)
qWarning("QApplication: Invalid Display* argument");
@@ -892,7 +890,7 @@ QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
}
QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
- : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient))
+ : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient, _internal))
{
if (! dpy)
qWarning("QApplication: Invalid Display* argument");
@@ -917,7 +915,7 @@ QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
*/
QApplication::QApplication(Display *dpy, int &argc, char **argv,
Qt::HANDLE visual, Qt::HANDLE colormap)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
{
if (! dpy)
qWarning("QApplication: Invalid Display* argument");
@@ -927,7 +925,7 @@ QApplication::QApplication(Display *dpy, int &argc, char **argv,
QApplication::QApplication(Display *dpy, int &argc, char **argv,
Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
{
if (! dpy)
qWarning("QApplication: Invalid Display* argument");
@@ -3732,11 +3730,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->checkReceiverThread(receiver);
#endif
-#ifdef QT3_SUPPORT
- if (e->type() == QEvent::ChildRemoved && !receiver->d_func()->pendingChildInsertedEvents.isEmpty())
- receiver->d_func()->removePendingChildInsertedEvents(static_cast<QChildEvent *>(e)->child());
-#endif // QT3_SUPPORT
-
// capture the current mouse/keyboard state
if(e->spontaneous()) {
if (e->type() == QEvent::KeyPress
@@ -5839,12 +5832,12 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
#ifndef QT_NO_GESTURES
QGestureManager* QGestureManager::instance()
{
- if (QApplicationPrivate *qAppPriv = QApplicationPrivate::instance()) {
- if (!qAppPriv->gestureManager)
- qAppPriv->gestureManager = new QGestureManager(qApp);
- return qAppPriv->gestureManager;
- }
- return 0;
+ QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
+ if (!qAppPriv)
+ return 0;
+ if (!qAppPriv->gestureManager)
+ qAppPriv->gestureManager = new QGestureManager(qApp);
+ return qAppPriv->gestureManager;
}
#endif // QT_NO_GESTURES
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 02425825d0..a790c6944d 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -123,15 +123,15 @@ public:
#endif
#ifndef qdoc
- QApplication(int &argc, char **argv, int = QT_VERSION);
- QApplication(int &argc, char **argv, bool GUIenabled, int = QT_VERSION);
- QApplication(int &argc, char **argv, Type, int = QT_VERSION);
+ QApplication(int &argc, char **argv, int = ApplicationFlags);
+ QApplication(int &argc, char **argv, bool GUIenabled, int = ApplicationFlags);
+ QApplication(int &argc, char **argv, Type, int = ApplicationFlags);
#if defined(Q_WS_X11)
- QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0, int = QT_VERSION);
- QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0, int = QT_VERSION);
+ QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0, int = ApplicationFlags);
+ QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0, int = ApplicationFlags);
#endif
#if defined(Q_OS_SYMBIAN)
- QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int = QT_VERSION);
+ QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int = ApplicationFlags);
#endif
#endif
virtual ~QApplication();
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index dd819e5ce3..c3f3e74a8a 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1243,6 +1243,8 @@ void qt_init(QApplicationPrivate *priv, int)
// Cocoa application delegate
#ifdef QT_MAC_USE_COCOA
NSApplication *cocoaApp = [QNSApplication sharedApplication];
+ qt_redirectNSApplicationSendEvent();
+
QMacCocoaAutoReleasePool pool;
NSObject *oldDelegate = [cocoaApp delegate];
QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
@@ -2608,25 +2610,26 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap
/*!
\fn bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event)
- \warning This virtual function is only implemented under Mac OS X when against Carbon.
+ \warning This virtual function is only used under Mac OS X, and behaves different
+ depending on if Qt is based on Carbon or Cocoa.
- If you create an application that inherits QApplication and reimplement
+ For the Carbon port, If you create an application that inherits QApplication and reimplement
this function, you get direct access to all Carbon Events that Qt registers
for from Mac OS X with this function being called with the \a caller and
the \a event.
+ For the Cocoa port, If you create an application that inherits QApplication and reimplement
+ this function, you get direct access to all Cocoa Events that Qt receives
+ from Mac OS X with this function being called with the \a caller being 0 and
+ the \a event being an NSEvent pointer:
+
+ NSEvent *e = reinterpret_cast<NSEvent *>(event);
+
Return true if you want to stop the event from being processed.
Return false for normal event dispatching. The default
implementation returns false.
- Cocoa uses a different event system which means this function is NOT CALLED
- when building Qt against Cocoa. If you want similar functionality subclass
- NSApplication and reimplement the sendEvent: message to handle all the
- NSEvents. You also will need to to instantiate your custom NSApplication
- before creating a QApplication. See \l
- {http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/Reference/Reference.html}{Apple's
- NSApplication Reference} for more information.
-
+ \sa macEventFilter(void *nsevent)
*/
bool QApplication::macEventFilter(EventHandlerCallRef, EventRef)
{
@@ -3107,11 +3110,7 @@ void onApplicationChangedActivation( bool activated )
}
if (!app->activeWindow()) {
-#if QT_MAC_USE_COCOA
- OSWindowRef wp = [NSApp keyWindow];
-#else
- OSWindowRef wp = ActiveNonFloatingWindow();
-#endif
+ OSWindowRef wp = [NSApp keyWindow];
if (QWidget *tmp_w = qt_mac_find_window(wp))
app->setActiveWindow(tmp_w);
}
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index aa3a6d52b4..18ec0dfabc 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -291,7 +291,7 @@ class Q_GUI_EXPORT QApplicationPrivate : public QCoreApplicationPrivate
{
Q_DECLARE_PUBLIC(QApplication)
public:
- QApplicationPrivate(int &argc, char **argv, QApplication::Type type);
+ QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags);
~QApplicationPrivate();
#if defined(Q_WS_X11)
@@ -491,8 +491,6 @@ public:
static QString styleOverride;
- static int app_compile_version;
-
#ifdef QT_KEYPAD_NAVIGATION
static QWidget *oldEditFocus;
static Qt::NavigationMode navigationMode;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index e9379180c7..fc4a7ccd96 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1389,7 +1389,7 @@ bool QSymbianControl::isControlActive()
This function is only available on S60.
*/
QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
{
Q_D(QApplication);
S60->s60ApplicationFactory = factory;
@@ -1397,7 +1397,7 @@ QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int
}
QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
{
Q_D(QApplication);
S60->s60ApplicationFactory = factory;
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 78028eb1f4..26f4ea7098 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -207,8 +207,6 @@ static void resolveAygLibs()
if (!aygResolved) {
aygResolved = true;
QSystemLibrary ayglib(QLatin1String("aygshell"));
- if (!ayglib.load())
- return;
ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture");
}
}
@@ -944,29 +942,36 @@ bool qt_nograb() // application no-grab option
typedef QHash<QString, int> WinClassNameHash;
Q_GLOBAL_STATIC(WinClassNameHash, winclassNames)
+//
+// If 0 is passed as the widget pointer, register a window class
+// for QWidget as default. This is used in QGLTemporaryContext
+// during GL initialization, where we don't want to use temporary
+// QWidgets or QGLWidgets, neither do we want to have separate code
+// to register window classes.
+//
const QString qt_reg_winclass(QWidget *w) // register window class
{
- int flags = w->windowFlags();
+ int flags = w ? w->windowFlags() : 0;
int type = flags & Qt::WindowType_Mask;
uint style;
bool icon;
QString cname;
- if (qt_widget_private(w)->isGLWidget) {
+ if (w && qt_widget_private(w)->isGLWidget) {
cname = QLatin1String("QGLWidget");
style = CS_DBLCLKS;
#ifndef Q_WS_WINCE
style |= CS_OWNDC;
#endif
icon = true;
- } else if (flags & Qt::MSWindowsOwnDC) {
+ } else if (w && (flags & Qt::MSWindowsOwnDC)) {
cname = QLatin1String("QWidgetOwnDC");
style = CS_DBLCLKS;
#ifndef Q_WS_WINCE
style |= CS_OWNDC;
#endif
icon = true;
- } else if (type == Qt::Tool || type == Qt::ToolTip){
+ } else if (w && (type == Qt::Tool || type == Qt::ToolTip)) {
style = CS_DBLCLKS;
if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) {
if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
@@ -981,7 +986,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class
style |= CS_SAVEBITS;
#endif
icon = false;
- } else if (type == Qt::Popup) {
+ } else if (w && (type == Qt::Popup)) {
cname = QLatin1String("QPopup");
style = CS_DBLCLKS;
#ifndef Q_WS_WINCE
@@ -1052,7 +1057,10 @@ const QString qt_reg_winclass(QWidget *w) // register window class
}
wc.hCursor = 0;
#ifndef Q_WS_WINCE
- wc.hbrBackground = qt_widget_private(w)->isGLWidget ? 0 : (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
+ HBRUSH brush = 0;
+ if (w && !qt_widget_private(w)->isGLWidget)
+ brush = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
+ wc.hbrBackground = brush;
#else
wc.hbrBackground = 0;
#endif
@@ -1074,8 +1082,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class
Q_GUI_EXPORT const QString qt_getRegisteredWndClass()
{
- QWidget w;
- return qt_reg_winclass(&w);
+ return qt_reg_winclass(0);
}
static void unregWinClasses()
@@ -3676,13 +3683,11 @@ static void initWinTabFunctions()
return;
QSystemLibrary library(QLatin1String("wintab32"));
- if (library.load()) {
- ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW");
- ptrWTGet = (PtrWTGet)library.resolve("WTGetW");
- ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable");
- ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
- ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
- }
+ ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW");
+ ptrWTGet = (PtrWTGet)library.resolve("WTGetW");
+ ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable");
+ ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
+ ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
#endif // Q_OS_WINCE
}
#endif // QT_NO_TABLETEVENT
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index e7b7ed8db0..b4cebd7cad 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -484,11 +484,9 @@ static void* qt_load_library_runtime(const char *library, int vernum,
Q_FOREACH(int version, versions) {
QLatin1String libName(library);
QLibrary xfixesLib(libName, version);
- if (xfixesLib.load()) {
- void *ptr = xfixesLib.resolve(symbol);
- if (ptr)
- return ptr;
- }
+ void *ptr = xfixesLib.resolve(symbol);
+ if (ptr)
+ return ptr;
}
return 0;
}
@@ -1740,6 +1738,9 @@ void qt_init(QApplicationPrivate *priv, int,
} else {
// Qt controls everything (default)
+ if (QApplication::testAttribute(Qt::AA_X11InitThreads))
+ XInitThreads();
+
// Set application name and class
char *app_class = 0;
if (argv && argv[0]) {
@@ -2585,22 +2586,20 @@ void qt_init(QApplicationPrivate *priv, int,
#if !defined (Q_OS_IRIX) && !defined (QT_NO_TABLET)
QLibrary wacom(QString::fromLatin1("wacomcfg"), 0); // version 0 is the latest release at time of writing this.
- if (wacom.load()) {
- // NOTE: C casts instead of reinterpret_cast for GCC 3.3.x
- ptrWacomConfigInit = (PtrWacomConfigInit)wacom.resolve("WacomConfigInit");
- ptrWacomConfigOpenDevice = (PtrWacomConfigOpenDevice)wacom.resolve("WacomConfigOpenDevice");
- ptrWacomConfigGetRawParam = (PtrWacomConfigGetRawParam)wacom.resolve("WacomConfigGetRawParam");
- ptrWacomConfigCloseDevice = (PtrWacomConfigCloseDevice)wacom.resolve("WacomConfigCloseDevice");
- ptrWacomConfigTerm = (PtrWacomConfigTerm)wacom.resolve("WacomConfigTerm");
-
- if (ptrWacomConfigInit == 0 || ptrWacomConfigOpenDevice == 0 || ptrWacomConfigGetRawParam == 0
- || ptrWacomConfigCloseDevice == 0 || ptrWacomConfigTerm == 0) { // either we have all, or we have none.
+ // NOTE: C casts instead of reinterpret_cast for GCC 3.3.x
+ ptrWacomConfigInit = (PtrWacomConfigInit)wacom.resolve("WacomConfigInit");
+ ptrWacomConfigOpenDevice = (PtrWacomConfigOpenDevice)wacom.resolve("WacomConfigOpenDevice");
+ ptrWacomConfigGetRawParam = (PtrWacomConfigGetRawParam)wacom.resolve("WacomConfigGetRawParam");
+ ptrWacomConfigCloseDevice = (PtrWacomConfigCloseDevice)wacom.resolve("WacomConfigCloseDevice");
+ ptrWacomConfigTerm = (PtrWacomConfigTerm)wacom.resolve("WacomConfigTerm");
+
+ if (ptrWacomConfigInit == 0 || ptrWacomConfigOpenDevice == 0 || ptrWacomConfigGetRawParam == 0
+ || ptrWacomConfigCloseDevice == 0 || ptrWacomConfigTerm == 0) { // either we have all, or we have none.
ptrWacomConfigInit = 0;
ptrWacomConfigOpenDevice = 0;
ptrWacomConfigGetRawParam = 0;
ptrWacomConfigCloseDevice = 0;
ptrWacomConfigTerm = 0;
- }
}
#endif
}
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index f7c0b6ee2a..8c7c333514 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -631,7 +631,7 @@ QByteArray QMimeDataWrapper::encodedData(const char *format) const
return data->data(QLatin1String(format));
} else{
QVariant variant = data->imageData();
- QImage img = qVariantValue<QImage>(variant);
+ QImage img = qvariant_cast<QImage>(variant);
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm
index 496286374a..9270213279 100644
--- a/src/gui/kernel/qcocoaapplication_mac.mm
+++ b/src/gui/kernel/qcocoaapplication_mac.mm
@@ -78,6 +78,7 @@
#include <private/qcocoaapplication_mac_p.h>
#include <private/qcocoaapplicationdelegate_mac_p.h>
#include <private/qt_cocoa_helpers_mac_p.h>
+#include <private/qcocoaintrospection_p.h>
QT_USE_NAMESPACE
@@ -116,12 +117,30 @@ QT_USE_NAMESPACE
quint64 lower = [event data1];
quint64 upper = [event data2];
QCocoaPostMessageArgs *args = reinterpret_cast<QCocoaPostMessageArgs *>(lower | (upper << 32));
- [args->target performSelector:args->selector];
+ // Special case for convenience: if the argument is an NSNumber, we unbox it directly.
+ // Use NSValue instead if this behaviour is unwanted.
+ id a1 = ([args->arg1 isKindOfClass:[NSNumber class]]) ? (id)[args->arg1 intValue] : args->arg1;
+ id a2 = ([args->arg2 isKindOfClass:[NSNumber class]]) ? (id)[args->arg2 intValue] : args->arg2;
+ switch (args->argCount) {
+ case 0:
+ [args->target performSelector:args->selector];
+ break;
+ case 1:
+ [args->target performSelector:args->selector withObject:a1];
+ break;
+ case 3:
+ [args->target performSelector:args->selector withObject:a1 withObject:a2];
+ break;
+ }
+
delete args;
}
-- (BOOL)qt_sendEvent:(NSEvent *)event
+- (BOOL)qt_filterEvent:(NSEvent *)event
{
+ if (qApp->macEventFilter(0, reinterpret_cast<EventRef>(event)))
+ return true;
+
if ([event type] == NSApplicationDefined) {
switch ([event subtype]) {
case QtCocoaEventSubTypePostMessage:
@@ -138,20 +157,55 @@ QT_USE_NAMESPACE
@implementation QNSApplication
-// WARNING: If Qt did not create NSApplication (this can e.g.
-// happend if Qt is used as a plugin from a 3rd-party cocoa
-// application), QNSApplication::sendEvent will never be called.
-// SO DO NOT RELY ON THIS FUNCTION BEING AVAILABLE.
-// Plugin developers that _do_ control the NSApplication sub-class
-// implementation of the 3rd-party application can call qt_sendEvent
-// from the sub-class event handler (like we do here) to work around
-// any issues.
+- (void)qt_sendEvent_original:(NSEvent *)event
+{
+ Q_UNUSED(event);
+ // This method will only be used as a signature
+ // template for the method we add into NSApplication
+ // containing the original [NSApplication sendEvent:] implementation
+}
+
+- (void)qt_sendEvent_replacement:(NSEvent *)event
+{
+ // This method (or its implementation to be precise) will
+ // be called instead of sendEvent if redirection occurs.
+ // 'self' will then be an instance of NSApplication
+ // (and not QNSApplication)
+ if (![NSApp qt_filterEvent:event])
+ [self qt_sendEvent_original:event];
+}
+
- (void)sendEvent:(NSEvent *)event
{
- if (![self qt_sendEvent:event])
+ // This method will be called if
+ // no redirection occurs
+ if (![NSApp qt_filterEvent:event])
[super sendEvent:event];
}
@end
+QT_BEGIN_NAMESPACE
+
+void qt_redirectNSApplicationSendEvent()
+{
+ if ([NSApp isMemberOfClass:[QNSApplication class]]) {
+ // No need to change implementation since Qt
+ // already controls a subclass of NSApplication
+ return;
+ }
+
+ // Change the implementation of [NSApplication sendEvent] to the
+ // implementation of qt_sendEvent_replacement found in QNSApplication.
+ // And keep the old implementation that gets overwritten inside a new
+ // method 'qt_sendEvent_original' that we add to NSApplication
+ qt_cocoa_change_implementation(
+ [NSApplication class],
+ @selector(sendEvent:),
+ [QNSApplication class],
+ @selector(qt_sendEvent_replacement:),
+ @selector(qt_sendEvent_original:));
+ }
+
+QT_END_NAMESPACE
#endif
diff --git a/src/gui/kernel/qcocoaapplication_mac_p.h b/src/gui/kernel/qcocoaapplication_mac_p.h
index 5569feb2df..c89ff36fff 100644
--- a/src/gui/kernel/qcocoaapplication_mac_p.h
+++ b/src/gui/kernel/qcocoaapplication_mac_p.h
@@ -101,11 +101,17 @@ QT_FORWARD_DECLARE_CLASS(QApplicationPrivate)
- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel;
- (void)qt_sendPostedMessage:(NSEvent *)event;
-- (BOOL)qt_sendEvent:(NSEvent *)event;
+- (BOOL)qt_filterEvent:(NSEvent *)event;
@end
@interface QNSApplication : NSApplication {
}
@end
+QT_BEGIN_NAMESPACE
+
+void qt_redirectNSApplicationSendEvent();
+
+QT_END_NAMESPACE
+
#endif
diff --git a/src/gui/kernel/qcocoaintrospection_mac.mm b/src/gui/kernel/qcocoaintrospection_mac.mm
new file mode 100644
index 0000000000..9b536b7a1e
--- /dev/null
+++ b/src/gui/kernel/qcocoaintrospection_mac.mm
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include <private/qcocoaintrospection_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel, SEL backupSel)
+{
+#ifndef QT_MAC_USE_COCOA
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
+#endif
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ // The following code replaces the _implementation_ for the selector we want to hack
+ // (originalSel) with the implementation found in proxyClass. Then it creates
+ // a new 'backup' method inside baseClass containing the old, original,
+ // implementation (fakeSel). You can let the proxy implementation of originalSel
+ // call fakeSel if needed (similar approach to calling a super class implementation).
+ // fakeSel must also be implemented in proxyClass, as the signature is used
+ // as template for the method one we add into baseClass.
+ // NB: You will typically never create any instances of proxyClass; we use it
+ // only for stealing its contents and put it into baseClass.
+ if (!replacementSel)
+ replacementSel = originalSel;
+
+ Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
+ Method replacementMethod = class_getInstanceMethod(proxyClass, replacementSel);
+ IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(replacementMethod));
+
+ if (backupSel) {
+ Method backupMethod = class_getInstanceMethod(proxyClass, backupSel);
+ class_addMethod(baseClass, backupSel, originalImp, method_getTypeEncoding(backupMethod));
+ }
+#endif
+ }
+}
+
+void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL backupSel)
+{
+#ifndef QT_MAC_USE_COCOA
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
+#endif
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
+ Method backupMethodInBaseClass = class_getInstanceMethod(baseClass, backupSel);
+ method_setImplementation(originalMethod, method_getImplementation(backupMethodInBaseClass));
+#endif
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qcocoaintrospection_p.h b/src/gui/kernel/qcocoaintrospection_p.h
new file mode 100644
index 0000000000..b9422e826e
--- /dev/null
+++ b/src/gui/kernel/qcocoaintrospection_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include <qglobal.h>
+#import <objc/objc-class.h>
+
+QT_BEGIN_NAMESPACE
+
+void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel = 0, SEL backupSel = 0);
+void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL backupSel);
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index ddf1a2738f..970bc0aeea 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -155,17 +155,6 @@ QT_END_NAMESPACE
- (void)sendEvent:(NSEvent *)event
{
- if ([event type] == NSApplicationDefined) {
- switch ([event subtype]) {
- case QtCocoaEventSubTypePostMessage:
- [NSApp qt_sendPostedMessage:event];
- return;
- default:
- break;
- }
- return;
- }
-
QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
// Cocoa can hold onto the window after we've disavowed its knowledge. So,
// if we get sent an event afterwards just have it go through the super's
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index a552ce7f6f..8576f52970 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -207,6 +207,7 @@ static int qCocoaViewCount = 0;
composing = false;
sendKeyEvents = true;
+ fromKeyDownEvent = false;
[self setHidden:YES];
return self;
}
@@ -508,7 +509,7 @@ static int qCocoaViewCount = 0;
}
// Make sure the opengl context is updated on resize.
- if (qwidgetprivate && qwidgetprivate->isGLWidget) {
+ if (qwidgetprivate && qwidgetprivate->isGLWidget && [self window]) {
qwidgetprivate->needWindowChange = true;
QEvent event(QEvent::MacGLWindowChange);
qApp->sendEvent(qwidget, &event);
@@ -532,14 +533,29 @@ static int qCocoaViewCount = 0;
if (!qwidget)
return;
+ // We use a different graphics system.
if (QApplicationPrivate::graphicsSystem() != 0) {
- if (qwidgetprivate->maybeBackingStore()) {
- // Drawing is handled on the window level
- // See qcocoasharedwindowmethods_mac_p.h
- if (!qwidget->testAttribute(Qt::WA_PaintOnScreen))
- return;
+
+ // Qt handles the painting occuring inside the window.
+ // Cocoa also keeps track of all widgets as NSView and therefore might
+ // ask for a repainting of a widget even if Qt is already taking care of it.
+ //
+ // The only valid reason for Cocoa to call drawRect: is for window manipulation
+ // (ie. resize, ...).
+ //
+ // Qt will then forward the update to the children.
+ if (qwidget->isWindow()) {
+ qwidget->update(qwidget->rect());
+ qwidgetprivate->syncBackingStore(qwidget->rect());
}
+
+ // Since we don't want to use the native engine, we must exit, however
+ // widgets that are set to paint on screen, spesifically QGLWidget,
+ // requires the following code to execute in order to be drawn.
+ if (!qwidget->testAttribute(Qt::WA_PaintOnScreen))
+ return;
}
+
CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
qwidgetprivate->hd = cg;
CGContextSaveGState(cg);
@@ -1203,7 +1219,9 @@ static int qCocoaViewCount = 0;
&& !(widgetToGetKey->inputMethodHints() & Qt::ImhDigitsOnly
|| widgetToGetKey->inputMethodHints() & Qt::ImhFormattedNumbersOnly
|| widgetToGetKey->inputMethodHints() & Qt::ImhHiddenText)) {
+ fromKeyDownEvent = true;
[qt_mac_nativeview_for(widgetToGetKey) interpretKeyEvents:[NSArray arrayWithObject: theEvent]];
+ fromKeyDownEvent = false;
}
if (sendKeyEvents && !composing) {
bool keyOK = qt_dispatchKeyEvent(theEvent, widgetToGetKey);
@@ -1273,7 +1291,10 @@ static int qCocoaViewCount = 0;
};
}
- if ([aString length] && composing) {
+ // When entering characters through Character Viewer or Keyboard Viewer, the text is passed
+ // through this insertText method. Since we dont receive a keyDown Event in such cases, the
+ // composing flag will be false.
+ if (([aString length] && composing) || !fromKeyDownEvent) {
// Send the commit string to the widget.
composing = false;
sendKeyEvents = false;
diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h
index b6b63ca3ca..5114233573 100644
--- a/src/gui/kernel/qcocoaview_mac_p.h
+++ b/src/gui/kernel/qcocoaview_mac_p.h
@@ -86,6 +86,7 @@ Q_GUI_EXPORT
bool composing;
int composingLength;
bool sendKeyEvents;
+ bool fromKeyDownEvent;
QString *composingText;
NSInteger dragEnterSequence;
}
diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h
index 2490d206fb..ed6b254f65 100644
--- a/src/gui/kernel/qcursor.h
+++ b/src/gui/kernel/qcursor.h
@@ -96,6 +96,10 @@ public:
QCursor(const QCursor &cursor);
~QCursor();
QCursor &operator=(const QCursor &cursor);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QCursor &operator=(QCursor &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
operator QVariant() const;
Qt::CursorShape shape() const;
diff --git a/src/gui/kernel/qdesktopwidget_win.cpp b/src/gui/kernel/qdesktopwidget_win.cpp
index 1b2dfe7a82..f65af9ca32 100644
--- a/src/gui/kernel/qdesktopwidget_win.cpp
+++ b/src/gui/kernel/qdesktopwidget_win.cpp
@@ -156,10 +156,8 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that)
#ifndef Q_OS_WINCE
QSystemLibrary user32Lib(QLatin1String("user32"));
- if (user32Lib.load()) {
- enumDisplayMonitors = (EnumFunc)user32Lib.resolve("EnumDisplayMonitors");
- getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW");
- }
+ enumDisplayMonitors = (EnumFunc)user32Lib.resolve("EnumDisplayMonitors");
+ getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW");
if (!enumDisplayMonitors || !getMonitorInfo) {
screenCount = GetSystemMetrics(80); // SM_CMONITORS
@@ -174,11 +172,9 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that)
getMonitorInfo = 0;
#else
QSystemLibrary coreLib(QLatin1String("coredll"));
- if (coreLib.load()) {
- // CE >= 4.0 case
- enumDisplayMonitors = (EnumFunc)coreLib.resolve("EnumDisplayMonitors");
- getMonitorInfo = (InfoFunc)coreLib.resolve("GetMonitorInfo");
- }
+ // CE >= 4.0 case
+ enumDisplayMonitors = (EnumFunc)coreLib.resolve("EnumDisplayMonitors");
+ getMonitorInfo = (InfoFunc)coreLib.resolve("GetMonitorInfo");
if ((!enumDisplayMonitors || !getMonitorInfo)) {
screenCount = GetSystemMetrics(SM_CMONITORS);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index eade02e7a3..d2b2098444 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -4392,7 +4392,7 @@ void QGestureEvent::accept(QGesture *gesture)
of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
Clearing the accept flag indicates that the event receiver does not
- want the gesture. Unwanted gestures may be propgated to the parent widget.
+ want the gesture. Unwanted gestures may be propagated to the parent widget.
\sa QGestureEvent::accept()
*/
diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp
index 377dfe3187..6e2ed76deb 100644
--- a/src/gui/kernel/qguifunctions_wince.cpp
+++ b/src/gui/kernel/qguifunctions_wince.cpp
@@ -129,8 +129,6 @@ static void resolveAygLibs()
if (!aygResolved) {
aygResolved = true;
QLibrary ayglib(QLatin1String("aygshell"));
- if (!ayglib.load())
- return;
ptrAygInitDialog = (AygInitDialog) ayglib.resolve("SHInitDialog");
ptrAygFullScreen = (AygFullScreen) ayglib.resolve("SHFullScreen");
ptrAygSHSipInfo = (AygSHSipInfo) ayglib.resolve("SHSipInfo");
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 50b2354156..e14a9198a6 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -76,7 +76,7 @@ static const MacSpecialKey entries[NumEntries] = {
{ Qt::Key_Backtab, 0x21E4 },
{ Qt::Key_Backspace, 0x232B },
{ Qt::Key_Return, 0x21B5 },
- { Qt::Key_Enter, 0x21B5 },
+ { Qt::Key_Enter, 0x2324 },
{ Qt::Key_Delete, 0x2326 },
{ Qt::Key_Home, 0x2196 },
{ Qt::Key_End, 0x2198 },
@@ -240,7 +240,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \i Paste \i Ctrl+V, Shift+Ins \i Ctrl+V \i Ctrl+V, F18, Shift+Ins \i Ctrl+V, F18, Shift+Ins \i Ctrl+V
\row \i Preferences \i \i Ctrl+, \i \i \i (none)
\row \i Undo \i Ctrl+Z, Alt+Backspace \i Ctrl+Z \i Ctrl+Z, F14 \i Ctrl+Z, F14 \i Ctrl+Z
- \row \i Redo \i Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \i Ctrl+Shift+Z, Ctrl+Y \i Ctrl+Shift+Z \i Ctrl+Shift+Z \i (none)
+ \row \i Redo \i Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \i Ctrl+Shift+Z \i Ctrl+Shift+Z \i Ctrl+Shift+Z \i (none)
\row \i Back \i Alt+Left, Backspace \i Ctrl+[ \i Alt+Left \i Alt+Left \i (none)
\row \i Forward \i Alt+Right, Shift+Backspace \i Ctrl+] \i Alt+Right \i Alt+Right \i (none)
\row \i Refresh \i F5 \i F5 \i F5 \i Ctrl+R, F5 \i (none)
@@ -718,7 +718,6 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = {
{QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, QApplicationPrivate::KB_Mac},
{QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, QApplicationPrivate::KB_All},
{QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_S60},
- {QKeySequence::Redo, 0, Qt::CTRL | Qt::Key_Y, QApplicationPrivate::KB_Mac},//different priority from above
{QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, QApplicationPrivate::KB_All},
{QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, QApplicationPrivate::KB_Mac},
{QKeySequence::Forward, 1, Qt::CTRL | Qt::Key_BracketRight, QApplicationPrivate::KB_Mac},
@@ -747,7 +746,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = {
{QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, QApplicationPrivate::KB_KDE},
{QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
{QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::Redo, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Mac}, //different priority from above
+ {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Mac},
{QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
{QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Mac },//different priority from above
{QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, QApplicationPrivate::KB_X11},
diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h
index 5a973e398c..b47873de90 100644
--- a/src/gui/kernel/qkeysequence.h
+++ b/src/gui/kernel/qkeysequence.h
@@ -179,6 +179,10 @@ public:
operator int() const;
int operator[](uint i) const;
QKeySequence &operator=(const QKeySequence &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QKeySequence &operator=(QKeySequence &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
bool operator==(const QKeySequence &other) const;
inline bool operator!= (const QKeySequence &other) const
{ return !(*this == other); }
diff --git a/src/gui/kernel/qlayoutitem.cpp b/src/gui/kernel/qlayoutitem.cpp
index 6a91d957e6..d1a82c22a4 100644
--- a/src/gui/kernel/qlayoutitem.cpp
+++ b/src/gui/kernel/qlayoutitem.cpp
@@ -516,9 +516,7 @@ bool QWidgetItem::hasHeightForWidth() const
{
if (isEmpty())
return false;
- if (wid->layout())
- return wid->layout()->hasHeightForWidth();
- return wid->sizePolicy().hasHeightForWidth();
+ return wid->d_func()->hasHeightForWidth();
}
/*!
diff --git a/src/gui/kernel/qmacdefines_mac.h b/src/gui/kernel/qmacdefines_mac.h
index d767470a66..d190d2384a 100644
--- a/src/gui/kernel/qmacdefines_mac.h
+++ b/src/gui/kernel/qmacdefines_mac.h
@@ -94,12 +94,6 @@ Yes, it is an informative comment ;-)
#include <QtCore/qglobal.h>
-#undef OLD_DEBUG
-#ifdef DEBUG
-# define OLD_DEBUG DEBUG
-# undef DEBUG
-#endif
-#define DEBUG 0
#ifdef qDebug
# define old_qDebug qDebug
# undef qDebug
@@ -179,12 +173,6 @@ typedef AERecord AppleEvent;
#undef check
#endif
-#undef DEBUG
-#ifdef OLD_DEBUG
-# define DEBUG OLD_DEBUG
-# undef OLD_DEBUG
-#endif
-
#ifdef old_qDebug
# undef qDebug
# define qDebug QT_NO_QDEBUG_MACRO
diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h
index f797f86eb5..7b7b41de62 100644
--- a/src/gui/kernel/qpalette.h
+++ b/src/gui/kernel/qpalette.h
@@ -78,6 +78,14 @@ public:
QPalette(const QPalette &palette);
~QPalette();
QPalette &operator=(const QPalette &palette);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QPalette &operator=(QPalette &&other)
+ {
+ resolve_mask = other.resolve_mask;
+ current_group = other.current_group;
+ qSwap(d, other.d); return *this;
+ }
+#endif
operator QVariant() const;
// Do not change the order, the serialization format depends on it
diff --git a/src/gui/kernel/qsizepolicy.h b/src/gui/kernel/qsizepolicy.h
index ff7b9ee6cd..26cc1e154d 100644
--- a/src/gui/kernel/qsizepolicy.h
+++ b/src/gui/kernel/qsizepolicy.h
@@ -62,12 +62,12 @@ private:
HSize = 4,
HMask = 0x0f,
VMask = HMask << HSize,
- CTShift = 9,
- CTSize = 5,
- WFHShift = CTShift + CTSize,
- CTMask = ((0x1 << CTSize) - 1) << CTShift,
- UnusedShift = CTShift + CTSize,
- UnusedSize = 2
+ CTShift = 9,
+ CTSize = 5,
+ CTMask = ((0x1 << CTSize) - 1) << CTShift,
+ WFHShift = CTShift + CTSize,
+ UnusedShift = WFHShift + 1,
+ UnusedSize = 1
};
public:
@@ -134,6 +134,8 @@ public:
void setHeightForWidth(bool b) { data = b ? (data | (1 << 2*HSize)) : (data & ~(1 << 2*HSize)); }
bool hasHeightForWidth() const { return data & (1 << 2*HSize); }
+ void setWidthForHeight(bool b) { data = b ? (data | (1 << (WFHShift))) : (data & ~(1 << (WFHShift))); }
+ bool hasWidthForHeight() const { return data & (1 << (WFHShift)); }
bool operator==(const QSizePolicy& s) const { return data == s.data; }
bool operator!=(const QSizePolicy& s) const { return data != s.data; }
@@ -200,15 +202,18 @@ private:
QSizePolicy(int i) : data(i) { }
quint32 data;
-/* use bit flags instead, keep it here for improved readability for now
+/* Qt5: Use bit flags instead, keep it here for improved readability for now.
+ We can maybe change it for Qt4, but we'd have to be careful, since the behaviour
+ is implementation defined. It usually varies between little- and big-endian compilers, but
+ it might also not vary.
quint32 horzPolicy : 4;
quint32 vertPolicy : 4;
quint32 hfw : 1;
quint32 ctype : 5;
quint32 wfh : 1;
quint32 padding : 1; // we cannot use the highest bit
- quint32 horStretch : 8;
quint32 verStretch : 8;
+ quint32 horStretch : 8;
*/
};
diff --git a/src/gui/kernel/qsizepolicy.qdoc b/src/gui/kernel/qsizepolicy.qdoc
index 7cd05c5949..f6a350c40c 100644
--- a/src/gui/kernel/qsizepolicy.qdoc
+++ b/src/gui/kernel/qsizepolicy.qdoc
@@ -249,7 +249,7 @@
Sets the flag determining whether the widget's preferred height
depends on its width, to \a dependent.
- \sa hasHeightForWidth()
+ \sa hasHeightForWidth(), setWidthForHeight()
*/
/*!
@@ -262,6 +262,28 @@
*/
/*!
+ \fn void QSizePolicy::setWidthForHeight(bool dependent)
+
+ Sets the flag determining whether the widget's width
+ depends on its height, to \a dependent.
+
+ This is only supported for QGraphicsLayout's subclasses.
+ It is not possible to have a layout with both height-for-width
+ and width-for-height constraints at the same time.
+
+ \sa hasWidthForHeight(), setHeightForWidth()
+*/
+
+/*!
+ \fn bool QSizePolicy::hasWidthForHeight() const
+
+ Returns true if the widget's width depends on its
+ height; otherwise returns false.
+
+ \sa setWidthForHeight()
+*/
+
+/*!
\fn bool QSizePolicy::operator==(const QSizePolicy &other) const
Returns true if this policy is equal to \a other; otherwise
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 7d23abff8a..88ff1e6730 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -469,7 +469,6 @@ void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec)
qt_sendSpontaneousEvent(qApp, &qtabletProximity);
}
-#ifdef QT_MAC_USE_COCOA
// Use this method to keep all the information in the TextSegment. As long as it is ordered
// we are in OK shape, and we can influence that ourselves.
struct KeyPair
@@ -493,69 +492,107 @@ bool operator<(QChar qchar, const KeyPair &entry)
return qchar < entry.cocoaKey;
}
+bool operator<(const Qt::Key &key, const KeyPair &entry)
+{
+ return key < entry.qtKey;
+}
+
+bool operator<(const KeyPair &entry, const Qt::Key &key)
+{
+ return entry.qtKey < key;
+}
+
+static bool qtKey2CocoaKeySortLessThan(const KeyPair &entry1, const KeyPair &entry2)
+{
+ return entry1.qtKey < entry2.qtKey;
+}
+
+static const int NumEntries = 59;
+static const KeyPair entries[NumEntries] = {
+ { NSEnterCharacter, Qt::Key_Enter },
+ { NSBackspaceCharacter, Qt::Key_Backspace },
+ { NSTabCharacter, Qt::Key_Tab },
+ { NSNewlineCharacter, Qt::Key_Return },
+ { NSCarriageReturnCharacter, Qt::Key_Return },
+ { NSBackTabCharacter, Qt::Key_Backtab },
+ { NSDeleteCharacter, Qt::Key_Delete },
+ { kEscapeCharCode, Qt::Key_Escape },
+ { NSUpArrowFunctionKey, Qt::Key_Up },
+ { NSDownArrowFunctionKey, Qt::Key_Down },
+ { NSLeftArrowFunctionKey, Qt::Key_Left },
+ { NSRightArrowFunctionKey, Qt::Key_Right },
+ { NSF1FunctionKey, Qt::Key_F1 },
+ { NSF2FunctionKey, Qt::Key_F2 },
+ { NSF3FunctionKey, Qt::Key_F3 },
+ { NSF4FunctionKey, Qt::Key_F4 },
+ { NSF5FunctionKey, Qt::Key_F5 },
+ { NSF6FunctionKey, Qt::Key_F6 },
+ { NSF7FunctionKey, Qt::Key_F7 },
+ { NSF8FunctionKey, Qt::Key_F8 },
+ { NSF9FunctionKey, Qt::Key_F8 },
+ { NSF10FunctionKey, Qt::Key_F10 },
+ { NSF11FunctionKey, Qt::Key_F11 },
+ { NSF12FunctionKey, Qt::Key_F12 },
+ { NSF13FunctionKey, Qt::Key_F13 },
+ { NSF14FunctionKey, Qt::Key_F14 },
+ { NSF15FunctionKey, Qt::Key_F15 },
+ { NSF16FunctionKey, Qt::Key_F16 },
+ { NSF17FunctionKey, Qt::Key_F17 },
+ { NSF18FunctionKey, Qt::Key_F18 },
+ { NSF19FunctionKey, Qt::Key_F19 },
+ { NSF20FunctionKey, Qt::Key_F20 },
+ { NSF21FunctionKey, Qt::Key_F21 },
+ { NSF22FunctionKey, Qt::Key_F22 },
+ { NSF23FunctionKey, Qt::Key_F23 },
+ { NSF24FunctionKey, Qt::Key_F24 },
+ { NSF25FunctionKey, Qt::Key_F25 },
+ { NSF26FunctionKey, Qt::Key_F26 },
+ { NSF27FunctionKey, Qt::Key_F27 },
+ { NSF28FunctionKey, Qt::Key_F28 },
+ { NSF29FunctionKey, Qt::Key_F29 },
+ { NSF30FunctionKey, Qt::Key_F30 },
+ { NSF31FunctionKey, Qt::Key_F31 },
+ { NSF32FunctionKey, Qt::Key_F32 },
+ { NSF33FunctionKey, Qt::Key_F33 },
+ { NSF34FunctionKey, Qt::Key_F34 },
+ { NSF35FunctionKey, Qt::Key_F35 },
+ { NSInsertFunctionKey, Qt::Key_Insert },
+ { NSDeleteFunctionKey, Qt::Key_Delete },
+ { NSHomeFunctionKey, Qt::Key_Home },
+ { NSEndFunctionKey, Qt::Key_End },
+ { NSPageUpFunctionKey, Qt::Key_PageUp },
+ { NSPageDownFunctionKey, Qt::Key_PageDown },
+ { NSPrintScreenFunctionKey, Qt::Key_Print },
+ { NSScrollLockFunctionKey, Qt::Key_ScrollLock },
+ { NSPauseFunctionKey, Qt::Key_Pause },
+ { NSSysReqFunctionKey, Qt::Key_SysReq },
+ { NSMenuFunctionKey, Qt::Key_Menu },
+ { NSHelpFunctionKey, Qt::Key_Help },
+};
+static const KeyPair * const end = entries + NumEntries;
+
+QChar qtKey2CocoaKey(Qt::Key key)
+{
+ // The first time this function is called, create a reverse
+ // looup table sorted on Qt Key rather than Cocoa key:
+ static QVector<KeyPair> rev_entries(NumEntries);
+ static bool mustInit = true;
+ if (mustInit){
+ mustInit = false;
+ for (int i=0; i<NumEntries; ++i)
+ rev_entries[i] = entries[i];
+ qSort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan);
+ }
+ const QVector<KeyPair>::iterator i
+ = qBinaryFind(rev_entries.begin(), rev_entries.end(), key);
+ if (i == rev_entries.end())
+ return QChar();
+ return i->cocoaKey;
+}
+
+#ifdef QT_MAC_USE_COCOA
static Qt::Key cocoaKey2QtKey(QChar keyCode)
{
- static const int NumEntries = 57;
- static const KeyPair entries[NumEntries] = {
- { NSEnterCharacter, Qt::Key_Enter },
- { NSTabCharacter, Qt::Key_Tab },
- { NSCarriageReturnCharacter, Qt::Key_Return },
- { NSBackTabCharacter, Qt::Key_Backtab },
- { kEscapeCharCode, Qt::Key_Escape },
- { NSDeleteCharacter, Qt::Key_Backspace },
- { NSUpArrowFunctionKey, Qt::Key_Up },
- { NSDownArrowFunctionKey, Qt::Key_Down },
- { NSLeftArrowFunctionKey, Qt::Key_Left },
- { NSRightArrowFunctionKey, Qt::Key_Right },
- { NSF1FunctionKey, Qt::Key_F1 },
- { NSF2FunctionKey, Qt::Key_F2 },
- { NSF3FunctionKey, Qt::Key_F3 },
- { NSF4FunctionKey, Qt::Key_F4 },
- { NSF5FunctionKey, Qt::Key_F5 },
- { NSF6FunctionKey, Qt::Key_F6 },
- { NSF7FunctionKey, Qt::Key_F7 },
- { NSF8FunctionKey, Qt::Key_F8 },
- { NSF9FunctionKey, Qt::Key_F8 },
- { NSF10FunctionKey, Qt::Key_F10 },
- { NSF11FunctionKey, Qt::Key_F11 },
- { NSF12FunctionKey, Qt::Key_F12 },
- { NSF13FunctionKey, Qt::Key_F13 },
- { NSF14FunctionKey, Qt::Key_F14 },
- { NSF15FunctionKey, Qt::Key_F15 },
- { NSF16FunctionKey, Qt::Key_F16 },
- { NSF17FunctionKey, Qt::Key_F17 },
- { NSF18FunctionKey, Qt::Key_F18 },
- { NSF19FunctionKey, Qt::Key_F19 },
- { NSF20FunctionKey, Qt::Key_F20 },
- { NSF21FunctionKey, Qt::Key_F21 },
- { NSF22FunctionKey, Qt::Key_F22 },
- { NSF23FunctionKey, Qt::Key_F23 },
- { NSF24FunctionKey, Qt::Key_F24 },
- { NSF25FunctionKey, Qt::Key_F25 },
- { NSF26FunctionKey, Qt::Key_F26 },
- { NSF27FunctionKey, Qt::Key_F27 },
- { NSF28FunctionKey, Qt::Key_F28 },
- { NSF29FunctionKey, Qt::Key_F29 },
- { NSF30FunctionKey, Qt::Key_F30 },
- { NSF31FunctionKey, Qt::Key_F31 },
- { NSF32FunctionKey, Qt::Key_F32 },
- { NSF33FunctionKey, Qt::Key_F33 },
- { NSF34FunctionKey, Qt::Key_F34 },
- { NSF35FunctionKey, Qt::Key_F35 },
- { NSInsertFunctionKey, Qt::Key_Insert },
- { NSDeleteFunctionKey, Qt::Key_Delete },
- { NSHomeFunctionKey, Qt::Key_Home },
- { NSEndFunctionKey, Qt::Key_End },
- { NSPageUpFunctionKey, Qt::Key_PageUp },
- { NSPageDownFunctionKey, Qt::Key_PageDown },
- { NSPrintScreenFunctionKey, Qt::Key_Print },
- { NSScrollLockFunctionKey, Qt::Key_ScrollLock },
- { NSPauseFunctionKey, Qt::Key_Pause },
- { NSSysReqFunctionKey, Qt::Key_SysReq },
- { NSMenuFunctionKey, Qt::Key_Menu },
- { NSHelpFunctionKey, Qt::Key_Help },
- };
- static const KeyPair * const end = entries + NumEntries;
const KeyPair *i = qBinaryFind(entries, end, keyCode);
if (i == end)
return Qt::Key(keyCode.unicode());
@@ -1204,7 +1241,7 @@ void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widge
// We have the original method here. Proceed and swap the methods.
method_exchangeImplementations(m1, m0);
widget->originalDrawMethod = false;
- [window display];
+ [theWindow display];
}
}
@@ -1227,7 +1264,7 @@ void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivat
}
method_exchangeImplementations(m1, m0);
widget->originalDrawMethod = true;
- [window display];
+ [theWindow display];
}
#endif // QT_MAC_USE_COCOA
@@ -1297,7 +1334,7 @@ CGContextRef qt_mac_graphicsContextFor(QWidget *widget)
CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
QDBeginCGContext(port, &context);
#else
- CGContextRef context = reinterpret_cast<CGContextRef>([[qt_mac_window_for(widget) graphicsContext] graphicsPort]);
+ CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort];
#endif
return context;
}
@@ -1426,39 +1463,17 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor)
[static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) set];
}
-// WARNING: If Qt did not create NSApplication (e.g. in case it is
-// used as a plugin), and at the same time, there is no window on
-// screen (or the window that the event is sendt to becomes hidden etc
-// before the event gets delivered), the message will not be performed.
-bool qt_cocoaPostMessage(id target, SEL selector)
+void qt_cocoaPostMessage(id target, SEL selector, int argCount, id arg1, id arg2)
{
- if (!target)
- return false;
-
- NSInteger windowNumber = 0;
- if (![NSApp isMemberOfClass:[QNSApplication class]]) {
- // INVARIANT: Cocoa is not using our NSApplication subclass. That means
- // we don't control the main event handler either. So target the event
- // for one of the windows on screen:
- NSWindow *nswin = [NSApp mainWindow];
- if (!nswin) {
- nswin = [NSApp keyWindow];
- if (!nswin)
- return false;
- }
- windowNumber = [nswin windowNumber];
- }
-
- // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
+ // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
// That is why we need to split the address in two parts:
- QCocoaPostMessageArgs *args = new QCocoaPostMessageArgs(target, selector);
+ QCocoaPostMessageArgs *args = new QCocoaPostMessageArgs(target, selector, argCount, arg1, arg2);
quint32 lower = quintptr(args);
quint32 upper = quintptr(args) >> 32;
NSEvent *e = [NSEvent otherEventWithType:NSApplicationDefined
- location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:windowNumber
+ location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:0
context:nil subtype:QtCocoaEventSubTypePostMessage data1:lower data2:upper];
[NSApp postEvent:e atStart:NO];
- return true;
}
#endif
@@ -1497,7 +1512,7 @@ void macDrawRectOnTop(void * /*OSWindowRef */window)
NSRect contentRect = [contentView frame];
// Draw a line on top of the already drawn line.
// We need to check if we are active or not to use the proper color.
- if([window isKeyWindow] || [window isMainWindow]) {
+ if([theWindow isKeyWindow] || [theWindow isMainWindow]) {
[[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
} else {
[[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
@@ -1517,7 +1532,7 @@ void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window)
{
OSWindowRef theWindow = static_cast<OSWindowRef>(window);
NSApplication *application = [NSApplication sharedApplication];
- NSToolbar *toolbar = [window toolbar];
+ NSToolbar *toolbar = [theWindow toolbar];
if([application isActive]) {
// Launched from finder
[toolbar setShowsBaselineSeparator:NO];
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index c6c2db2f39..5c233928f4 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -202,17 +202,25 @@ class QCocoaPostMessageArgs {
public:
id target;
SEL selector;
- QCocoaPostMessageArgs(id target, SEL selector) : target(target), selector(selector)
+ int argCount;
+ id arg1;
+ id arg2;
+ QCocoaPostMessageArgs(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0)
+ : target(target), selector(selector), argCount(argCount), arg1(arg1), arg2(arg2)
{
[target retain];
+ [arg1 retain];
+ [arg2 retain];
}
~QCocoaPostMessageArgs()
{
+ [arg2 release];
+ [arg1 release];
[target release];
}
};
-bool qt_cocoaPostMessage(id target, SEL selector);
+void qt_cocoaPostMessage(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0);
#endif
#endif
diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp
index c8fcf45773..88fdbc6428 100644
--- a/src/gui/kernel/qtooltip.cpp
+++ b/src/gui/kernel/qtooltip.cpp
@@ -353,7 +353,7 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
#ifndef QT_NO_STYLE_STYLESHEET
if (testAttribute(Qt::WA_StyleSheet) || (w && qobject_cast<QStyleSheetStyle *>(w->style()))) {
//the stylesheet need to know the real parent
- QTipLabel::instance->setProperty("_q_stylesheet_parent", qVariantFromValue(w));
+ QTipLabel::instance->setProperty("_q_stylesheet_parent", QVariant::fromValue(w));
//we force the style to be the QStyleSheetStyle, and force to clear the cache as well.
QTipLabel::instance->setStyleSheet(QLatin1String("/* */"));
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index dc0dbf479e..cffad1d4c6 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -1580,7 +1580,8 @@ QWidget::~QWidget()
d->needsFlush = 0;
// set all QPointers for this object to zero
- QObjectPrivate::clearGuards(this);
+ if (d->hasGuards)
+ QObjectPrivate::clearGuards(this);
if (d->declarativeData) {
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
@@ -1808,13 +1809,7 @@ void QWidgetPrivate::syncBackingStore()
repaint_sys(dirty);
dirty = QRegion();
} else if (QWidgetBackingStore *bs = maybeBackingStore()) {
-#ifdef QT_MAC_USE_COCOA
- Q_UNUSED(bs);
- void qt_mac_set_needs_display(QWidget *, QRegion);
- qt_mac_set_needs_display(q_func(), QRegion());
-#else
bs->sync();
-#endif
}
}
@@ -1823,13 +1818,7 @@ void QWidgetPrivate::syncBackingStore(const QRegion &region)
if (paintOnScreen())
repaint_sys(region);
else if (QWidgetBackingStore *bs = maybeBackingStore()) {
-#ifdef QT_MAC_USE_COCOA
- Q_UNUSED(bs);
- void qt_mac_set_needs_display(QWidget *, QRegion);
- qt_mac_set_needs_display(q_func(), region);
-#else
bs->sync(q_func(), region);
-#endif
}
}
@@ -6578,7 +6567,7 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
// that can take keyboard focus so that second is inserted after
// that last child, and the focus order within first is (more
// likely to be) preserved.
- QList<QWidget *> l = qFindChildren<QWidget *>(first);
+ QList<QWidget *> l = first->findChildren<QWidget *>();
for (int i = l.size()-1; i >= 0; --i) {
QWidget * next = l.at(i);
if (next->window() == fp->window()) {
@@ -9738,6 +9727,23 @@ int QWidget::heightForWidth(int w) const
return -1;
}
+
+/*!
+ \internal
+
+ *virtual private*
+
+ This is a bit hackish, but ideally we would have created a virtual function
+ in the public API (however, too late...) so that subclasses could reimplement
+ their own function.
+ Instead we add a virtual function to QWidgetPrivate.
+ ### Qt5: move to public class and make virtual
+*/
+bool QWidgetPrivate::hasHeightForWidth() const
+{
+ return layout ? layout->hasHeightForWidth() : size_policy.hasHeightForWidth();
+}
+
/*!
\fn QWidget *QWidget::childAt(int x, int y) const
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 941bd68929..980f40f07d 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -898,13 +898,6 @@ protected:
Q_DECLARE_OPERATORS_FOR_FLAGS(QWidget::RenderFlags)
-#if defined Q_CC_MSVC && _MSC_VER < 1300
-template <> inline QWidget *qobject_cast_helper<QWidget*>(QObject *o, QWidget *)
-{
- if (!o || !o->isWidgetType()) return 0;
- return (QWidget*)(o);
-}
-#else
template <> inline QWidget *qobject_cast<QWidget*>(QObject *o)
{
if (!o || !o->isWidgetType()) return 0;
@@ -915,7 +908,6 @@ template <> inline const QWidget *qobject_cast<const QWidget*>(const QObject *o)
if (!o || !o->isWidgetType()) return 0;
return static_cast<const QWidget*>(o);
}
-#endif
inline QWidget *QWidget::childAt(int ax, int ay) const
{ return childAt(QPoint(ax, ay)); }
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 1e2aa9f848..5e41efa42e 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -226,6 +226,8 @@ static NSDrawer *qt_mac_drawer_for(const QWidget *widget)
for (NSWindow *window in windows) {
NSArray *drawers = [window drawers];
for (NSDrawer *drawer in drawers) {
+ if ([drawer contentView] == widgetView)
+ return drawer;
NSArray *views = [[drawer contentView] subviews];
for (NSView *view in views) {
if (view == widgetView)
@@ -240,6 +242,9 @@ static NSDrawer *qt_mac_drawer_for(const QWidget *widget)
static void qt_mac_destructView(OSViewRef view)
{
#ifdef QT_MAC_USE_COCOA
+ NSWindow *window = [view window];
+ if ([window contentView] == view)
+ [window setContentView:[[NSView alloc] initWithFrame:[view bounds]]];
[view removeFromSuperview];
[view release];
#else
@@ -2294,28 +2299,23 @@ void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWin
Q_UNUSED(dialog);
data.fstrut_dirty = true; // when we create a toplevel widget, the frame strut should be dirty
+
OSViewRef nsview = (OSViewRef)data.winid;
- OSViewRef window_contentview = qt_mac_get_contentview_for(windowRef);
if (!nsview) {
- nsview = qt_mac_create_widget(q, this, window_contentview);
+ nsview = qt_mac_create_widget(q, this, 0);
setWinId(WId(nsview));
- } else {
- [window_contentview addSubview:nsview];
- }
- if (nsview) {
- NSRect bounds = [window_contentview bounds];
- [nsview setFrame:bounds];
- [nsview setHidden:NO];
- if (q->testAttribute(Qt::WA_DropSiteRegistered))
- registerDropSite(true);
- transferChildren();
-
- // Tell Cocoa explicit that we wan't the view to receive key events
- // (regardless of focus policy) because this is how it works on other
- // platforms (and in the carbon port):
- if (!qApp->focusWidget())
- [windowRef makeFirstResponder:nsview];
}
+ [windowRef setContentView:nsview];
+ [nsview setHidden:NO];
+ if (q->testAttribute(Qt::WA_DropSiteRegistered))
+ registerDropSite(true);
+ transferChildren();
+
+ // Tell Cocoa explicit that we wan't the view to receive key events
+ // (regardless of focus policy) because this is how it works on other
+ // platforms (and in the carbon port):
+ if (!qApp->focusWidget())
+ [windowRef makeFirstResponder:nsview];
if (topExtra->posFromMove) {
updateFrameStrut();
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 4a79dc7932..c943bd80a8 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -542,6 +542,7 @@ public:
bool setMinimumSize_helper(int &minw, int &minh);
bool setMaximumSize_helper(int &maxw, int &maxh);
+ virtual bool hasHeightForWidth() const;
void setConstraints_sys();
bool pointInsideRectAndMask(const QPoint &) const;
QWidget *childAt_helper(const QPoint &, bool) const;
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 4109ed80a4..91e74b558d 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -360,7 +360,9 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
if (!q->testAttribute(Qt::WA_Moved) && !q->testAttribute(Qt::WA_DontShowOnScreen))
data.crect.moveTopLeft(QPoint(clientRect.iTl.iX, clientRect.iTl.iY));
- QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) );
+ QScopedPointer<QSymbianControl> control( new QSymbianControl(q) );
+ Q_CHECK_PTR(control);
+
QT_TRAP_THROWING(control->ConstructL(true, desktop));
control->SetMopParent(static_cast<CEikAppUi*>(S60->appUi()));
@@ -405,7 +407,9 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
} else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create native child widget
- QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) );
+ QScopedPointer<QSymbianControl> control( new QSymbianControl(q) );
+ Q_CHECK_PTR(control);
+
QT_TRAP_THROWING(control->ConstructL(!parentWidget));
// Symbian windows are always created in an inactive state
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 3d206fdefc..39ed7500f1 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -1635,8 +1635,6 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
}
}
-extern Q_GUI_EXPORT HDC qt_win_display_dc();
-
int QWidget::metric(PaintDeviceMetric m) const
{
Q_D(const QWidget);
@@ -1646,7 +1644,7 @@ int QWidget::metric(PaintDeviceMetric m) const
} else if (m == PdmHeight) {
val = data->crect.height();
} else {
- HDC gdc = qt_win_display_dc();
+ HDC gdc = GetDC(0);
switch (m) {
case PdmDpiX:
case PdmPhysicalDpiX:
@@ -1697,6 +1695,7 @@ int QWidget::metric(PaintDeviceMetric m) const
val = 0;
qWarning("QWidget::metric: Invalid metric command");
}
+ ReleaseDC(0, gdc);
}
return val;
}
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 16c7f97d43..2f03bd08a0 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -102,8 +102,6 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
\sa optimize()
*/
-#if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
-
/*!
\fn QMatrix4x4::QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
@@ -112,7 +110,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
the remaining elements are filled with elements from the identity
matrix.
- \sa toGenericMatrix(), qGenericMatrixToMatrix4x4()
+ \sa toGenericMatrix()
*/
/*!
@@ -122,34 +120,32 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
top-most M rows of this 4x4 matrix. If N or M is greater than 4,
then the remaining elements are filled with elements from the
identity matrix.
-
- \sa qGenericMatrixFromMatrix4x4()
*/
-#endif
-
/*!
\fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
\relates QMatrix4x4
+ \obsolete
Returns a 4x4 matrix constructed from the left-most 4 columns and
top-most 4 rows of \a matrix. If \a matrix has less than 4 columns
or rows, the remaining elements are filled with elements from the
identity matrix.
- \sa qGenericMatrixFromMatrix4x4()
+ \sa QMatrix4x4(const QGenericMatrix &)
*/
/*!
\fn QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
\relates QMatrix4x4
+ \obsolete
Returns a NxM generic matrix constructed from the left-most N columns
and top-most M rows of \a matrix. If N or M is greater than 4,
then the remaining elements are filled with elements from the
identity matrix.
- \sa qGenericMatrixToMatrix4x4(), QMatrix4x4::toGenericMatrix()
+ \sa QMatrix4x4::toGenericMatrix()
*/
/*!
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index 0671fa8829..598058cdcb 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -69,10 +69,10 @@ public:
qreal m21, qreal m22, qreal m23, qreal m24,
qreal m31, qreal m32, qreal m33, qreal m34,
qreal m41, qreal m42, qreal m43, qreal m44);
-#if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
+
template <int N, int M>
explicit QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix);
-#endif
+
QMatrix4x4(const qreal *values, int cols, int rows);
QMatrix4x4(const QTransform& transform);
QMatrix4x4(const QMatrix& matrix);
@@ -169,10 +169,8 @@ public:
QRect mapRect(const QRect& rect) const;
QRectF mapRect(const QRectF& rect) const;
-#if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
template <int N, int M>
QGenericMatrix<N, M, qreal> toGenericMatrix() const;
-#endif
inline qreal *data();
inline const qreal *data() const { return m[0]; }
@@ -223,8 +221,6 @@ inline QMatrix4x4::QMatrix4x4
flagBits = General;
}
-#if !defined(QT_NO_MEMBER_TEMPLATES)
-
template <int N, int M>
Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4
(const QGenericMatrix<N, M, qreal>& matrix)
@@ -261,8 +257,6 @@ QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const
return result;
}
-#endif
-
inline const qreal& QMatrix4x4::operator()(int aRow, int aColumn) const
{
Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
@@ -992,14 +986,15 @@ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QMatrix4x4 &);
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix4x4 &);
#endif
+#ifdef QT_DEPRECATED
template <int N, int M>
-QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
+QT_DEPRECATED QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
{
return QMatrix4x4(matrix.constData(), N, M);
}
template <int N, int M>
-QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
+QT_DEPRECATED QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
{
QGenericMatrix<N, M, qreal> result;
const qreal *m = matrix.constData();
@@ -1016,6 +1011,7 @@ QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix
}
return result;
}
+#endif
#endif
diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h
index b65730144a..efc720b12f 100644
--- a/src/gui/painting/qbrush.h
+++ b/src/gui/painting/qbrush.h
@@ -92,6 +92,10 @@ public:
~QBrush();
QBrush &operator=(const QBrush &brush);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QBrush &operator=(QBrush &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
operator QVariant() const;
inline Qt::BrushStyle style() const;
diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp
index bf03545383..72e5833c5b 100644
--- a/src/gui/painting/qoutlinemapper.cpp
+++ b/src/gui/painting/qoutlinemapper.cpp
@@ -47,8 +47,6 @@
QT_BEGIN_NAMESPACE
-static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-
#define qreal_to_fixed_26_6(f) (int(f * 64))
@@ -216,13 +214,6 @@ void QOutlineMapper::endOutline()
elements = m_elements_dev.data();
}
- if (m_round_coords) {
- // round coordinates to match outlines drawn with drawLine_midpoint_i
- for (int i = 0; i < m_elements.size(); ++i)
- elements[i] = QPointF(qFloor(elements[i].x() + aliasedCoordinateDelta),
- qFloor(elements[i].y() + aliasedCoordinateDelta));
- }
-
controlPointRect = boundingRect(elements, element_count);
#ifdef QT_DEBUG_CONVERT
diff --git a/src/gui/painting/qoutlinemapper_p.h b/src/gui/painting/qoutlinemapper_p.h
index d534f76c15..fcfc9bf454 100644
--- a/src/gui/painting/qoutlinemapper_p.h
+++ b/src/gui/painting/qoutlinemapper_p.h
@@ -95,8 +95,7 @@ public:
m_tags(0),
m_contours(0),
m_polygon_dev(0),
- m_in_clip_elements(false),
- m_round_coords(false)
+ m_in_clip_elements(false)
{
}
@@ -202,8 +201,6 @@ public:
QT_FT_Outline *convertPath(const QPainterPath &path);
QT_FT_Outline *convertPath(const QVectorPath &path);
- void setCoordinateRounding(bool coordinateRounding) { m_round_coords = coordinateRounding; }
-
inline QPainterPath::ElementType *elementTypes() const { return m_element_types.size() == 0 ? 0 : m_element_types.data(); }
public:
@@ -237,9 +234,6 @@ public:
bool m_valid;
bool m_in_clip_elements;
-
-private:
- bool m_round_coords;
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index 3a4c94ce1c..d4a8213b1c 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -130,7 +130,7 @@ QPaintBufferPrivate::~QPaintBufferPrivate()
for (int i = 0; i < commands.size(); ++i) {
const QPaintBufferCommand &cmd = commands.at(i);
if (cmd.id == QPaintBufferPrivate::Cmd_DrawTextItem)
- delete reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(variants.at(cmd.offset)));
+ delete reinterpret_cast<QTextItemIntCopy *>(qvariant_cast<void *>(variants.at(cmd.offset)));
}
}
@@ -330,7 +330,7 @@ QString QPaintBuffer::commandDescription(int command) const
break; }
case QPaintBufferPrivate::Cmd_SetBrush: {
- QBrush brush = qVariantValue<QBrush>(d_ptr->variants.at(cmd.offset));
+ QBrush brush = qvariant_cast<QBrush>(d_ptr->variants.at(cmd.offset));
debug << "Cmd_SetBrush: " << brush;
break; }
@@ -354,27 +354,27 @@ QString QPaintBuffer::commandDescription(int command) const
break; }
case QPaintBufferPrivate::Cmd_StrokeVectorPath: {
- QPen pen = qVariantValue<QPen>(d_ptr->variants.at(cmd.extra));
+ QPen pen = qvariant_cast<QPen>(d_ptr->variants.at(cmd.extra));
debug << "ExCmd_StrokeVectorPath: size: " << cmd.size
// << ", hints:" << d->ints[cmd.offset2+cmd.size]
<< "pts/elms:" << cmd.offset << cmd.offset2 << pen;
break; }
case QPaintBufferPrivate::Cmd_FillVectorPath: {
- QBrush brush = qVariantValue<QBrush>(d_ptr->variants.at(cmd.extra));
+ QBrush brush = qvariant_cast<QBrush>(d_ptr->variants.at(cmd.extra));
debug << "ExCmd_FillVectorPath: size: " << cmd.size
// << ", hints:" << d->ints[cmd.offset2+cmd.size]
<< "pts/elms:" << cmd.offset << cmd.offset2 << brush;
break; }
case QPaintBufferPrivate::Cmd_FillRectBrush: {
- QBrush brush = qVariantValue<QBrush>(d_ptr->variants.at(cmd.extra));
+ QBrush brush = qvariant_cast<QBrush>(d_ptr->variants.at(cmd.extra));
QRectF *rect = (QRectF *)(d_ptr->floats.constData() + cmd.offset);
debug << "ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush;
break; }
case QPaintBufferPrivate::Cmd_FillRectColor: {
- QColor color = qVariantValue<QColor>(d_ptr->variants.at(cmd.extra));
+ QColor color = qvariant_cast<QColor>(d_ptr->variants.at(cmd.extra));
QRectF *rect = (QRectF *)(d_ptr->floats.constData() + cmd.offset);
debug << "ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color;
break; }
@@ -451,12 +451,12 @@ QString QPaintBuffer::commandDescription(int command) const
break; }
case QPaintBufferPrivate::Cmd_SetPen: {
- QPen pen = qVariantValue<QPen>(d_ptr->variants.at(cmd.offset));
+ QPen pen = qvariant_cast<QPen>(d_ptr->variants.at(cmd.offset));
debug << "Cmd_SetPen: " << pen;
break; }
case QPaintBufferPrivate::Cmd_SetTransform: {
- QTransform xform = qVariantValue<QTransform>(d_ptr->variants.at(cmd.offset));
+ QTransform xform = qvariant_cast<QTransform>(d_ptr->variants.at(cmd.offset));
debug << "Cmd_SetTransform, offset: " << cmd.offset << xform;
break; }
@@ -532,7 +532,7 @@ QString QPaintBuffer::commandDescription(int command) const
case QPaintBufferPrivate::Cmd_DrawTextItem: {
QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1));
- QTextItemIntCopy *tiCopy = reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(d_ptr->variants.at(cmd.offset)));
+ QTextItemIntCopy *tiCopy = reinterpret_cast<QTextItemIntCopy *>(qvariant_cast<void *>(d_ptr->variants.at(cmd.offset)));
QTextItemInt &ti = (*tiCopy)();
QString text(ti.text());
@@ -1287,7 +1287,7 @@ void QPaintBufferEngine::drawTextItem(const QPointF &pos, const QTextItem &ti)
qDebug() << "QPaintBufferEngine: drawTextItem: pos:" << pos << ti.text();
#endif
if (m_stream_raw_text_items) {
- QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawTextItem, qVariantFromValue<void *>(new QTextItemIntCopy(ti)));
+ QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawTextItem, QVariant::fromValue<void *>(new QTextItemIntCopy(ti)));
QFont font(ti.font());
font.setUnderline(false);
@@ -1429,7 +1429,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_SetPen: {
- QPen pen = qVariantValue<QPen>(d->variants.at(cmd.offset));
+ QPen pen = qvariant_cast<QPen>(d->variants.at(cmd.offset));
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> Cmd_SetPen: " << pen;
#endif
@@ -1437,7 +1437,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_SetBrush: {
- QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.offset));
+ QBrush brush = qvariant_cast<QBrush>(d->variants.at(cmd.offset));
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> Cmd_SetBrush: " << brush;
#endif
@@ -1452,7 +1452,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_SetTransform: {
- QTransform xform = qVariantValue<QTransform>(d->variants.at(cmd.offset));
+ QTransform xform = qvariant_cast<QTransform>(d->variants.at(cmd.offset));
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> Cmd_SetTransform, offset: " << cmd.offset << xform;
#endif
@@ -1520,7 +1520,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_StrokeVectorPath: {
- QPen pen = qVariantValue<QPen>(d->variants.at(cmd.extra));
+ QPen pen = qvariant_cast<QPen>(d->variants.at(cmd.extra));
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> Cmd_StrokeVectorPath: size: " << cmd.size
// << ", hints:" << d->ints[cmd.offset2+cmd.size]
@@ -1531,7 +1531,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_FillVectorPath: {
- QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra));
+ QBrush brush = qvariant_cast<QBrush>(d->variants.at(cmd.extra));
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> Cmd_FillVectorPath: size: " << cmd.size
// << ", hints:" << d->ints[cmd.offset2+cmd.size]
@@ -1705,7 +1705,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_FillRectBrush: {
- QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra));
+ QBrush brush = qvariant_cast<QBrush>(d->variants.at(cmd.extra));
QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset);
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> Cmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush;
@@ -1714,7 +1714,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_FillRectColor: {
- QColor color = qVariantValue<QColor>(d->variants.at(cmd.extra));
+ QColor color = qvariant_cast<QColor>(d->variants.at(cmd.extra));
QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset);
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> Cmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color;
@@ -1790,7 +1790,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
case QPaintBufferPrivate::Cmd_DrawTextItem: {
QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1));
- QTextItemIntCopy *tiCopy = reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(d->variants.at(cmd.offset)));
+ QTextItemIntCopy *tiCopy = reinterpret_cast<QTextItemIntCopy *>(qvariant_cast<void *>(d->variants.at(cmd.offset)));
QTextItemInt &ti = (*tiCopy)();
QString text(ti.text());
@@ -1885,7 +1885,7 @@ void QPaintEngineExReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_StrokeVectorPath: {
- QPen pen = qVariantValue<QPen>(d->variants.at(cmd.extra));
+ QPen pen = qvariant_cast<QPen>(d->variants.at(cmd.extra));
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> ExCmd_StrokeVectorPath: size: " << cmd.size
// << ", hints:" << d->ints[cmd.offset2+cmd.size]
@@ -1896,7 +1896,7 @@ void QPaintEngineExReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_FillVectorPath: {
- QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra));
+ QBrush brush = qvariant_cast<QBrush>(d->variants.at(cmd.extra));
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> ExCmd_FillVectorPath: size: " << cmd.size
// << ", hints:" << d->ints[cmd.offset2+cmd.size]
@@ -1907,7 +1907,7 @@ void QPaintEngineExReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_FillRectBrush: {
- QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra));
+ QBrush brush = qvariant_cast<QBrush>(d->variants.at(cmd.extra));
QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset);
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush;
@@ -1916,7 +1916,7 @@ void QPaintEngineExReplayer::process(const QPaintBufferCommand &cmd)
break; }
case QPaintBufferPrivate::Cmd_FillRectColor: {
- QColor color = qVariantValue<QColor>(d->variants.at(cmd.extra));
+ QColor color = qvariant_cast<QColor>(d->variants.at(cmd.extra));
QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset);
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << " -> ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 09a87aa252..94d7578593 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -123,9 +123,6 @@ void dumpClip(int width, int height, const QClipData *clip);
// 4 pixels.
#define int_dim(pos, dim) (int(pos+dim) - int(pos))
-// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
-static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-
#ifdef Q_WS_WIN
extern bool qt_cleartype_enabled;
#endif
@@ -1753,10 +1750,10 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
static inline QRect toNormalizedFillRect(const QRectF &rect)
{
- int x1 = qRound(rect.x() + aliasedCoordinateDelta);
- int y1 = qRound(rect.y() + aliasedCoordinateDelta);
- int x2 = qRound(rect.right() + aliasedCoordinateDelta);
- int y2 = qRound(rect.bottom() + aliasedCoordinateDelta);
+ int x1 = qRound(rect.x());
+ int y1 = qRound(rect.y());
+ int x2 = qRound(rect.right());
+ int y2 = qRound(rect.bottom());
if (x2 < x1)
qSwap(x1, x2);
@@ -2025,7 +2022,6 @@ void QRasterPaintEngine::fillPolygon(const QPointF *points, int pointCount, Poly
*/
void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
- Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
#ifdef QT_DEBUG_DRAW
@@ -2046,9 +2042,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
if (mode != PolylineMode) {
// Do the fill...
if (s->brushData.blend) {
- d->outlineMapper->setCoordinateRounding(s->penData.blend && s->flags.fast_pen && s->lastPen.brush().isOpaque());
fillPolygon(points, pointCount, mode);
- d->outlineMapper->setCoordinateRounding(false);
}
}
@@ -2100,7 +2094,6 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
if (s->brushData.blend) {
// Compose polygon fill..,
ensureOutlineMapper();
- d->outlineMapper->setCoordinateRounding(s->penData.blend != 0);
d->outlineMapper->beginOutline(mode == WindingMode ? Qt::WindingFill : Qt::OddEvenFill);
d->outlineMapper->moveTo(*points);
const QPoint *p = points;
@@ -2114,7 +2107,6 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
ProcessSpans brushBlend = d->getBrushFunc(d->outlineMapper->controlPointRect,
&s->brushData);
d->rasterize(d->outlineMapper->outline(), brushBlend, &s->brushData, d->rasterBuffer.data());
- d->outlineMapper->setCoordinateRounding(false);
}
}
@@ -2162,13 +2154,11 @@ void QRasterPaintEngine::strokePolygonCosmetic(const QPointF *points, int pointC
: LineDrawNormal);
int dashOffset = int(s->lastPen.dashOffset());
- const QPointF offs(aliasedCoordinateDelta, aliasedCoordinateDelta);
-
// Draw all the line segments.
for (int i=1; i<pointCount; ++i) {
- QPointF lp1 = points[i-1] * s->matrix + offs;
- QPointF lp2 = points[i] * s->matrix + offs;
+ QPointF lp1 = points[i-1] * s->matrix;
+ QPointF lp2 = points[i] * s->matrix;
const QRectF brect(lp1, lp2);
ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
@@ -2190,8 +2180,8 @@ void QRasterPaintEngine::strokePolygonCosmetic(const QPointF *points, int pointC
// Polygons are implicitly closed.
if (needs_closing) {
- QPointF lp1 = points[pointCount-1] * s->matrix + offs;
- QPointF lp2 = points[0] * s->matrix + offs;
+ QPointF lp1 = points[pointCount-1] * s->matrix;
+ QPointF lp2 = points[0] * s->matrix;
const QRectF brect(lp1, lp2);
ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
@@ -2579,10 +2569,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
int sr_b = qCeil(sr.bottom()) - 1;
if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
- // as fillRect will apply the aliased coordinate delta we need to
- // subtract it here as we don't use it for image drawing
QTransform old = s->matrix;
- s->matrix = s->matrix * QTransform::fromTranslate(-aliasedCoordinateDelta, -aliasedCoordinateDelta);
// Do whatever fillRect() does, but without premultiplying the color if it's already premultiplied.
QRgb color = img.pixel(sr_l, sr_t);
@@ -2726,11 +2713,9 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
d->initializeRasterizer(&d->image_filler_xform);
d->rasterizer->setAntialiased(s->flags.antialiased);
- const QPointF offs = s->flags.antialiased ? QPointF() : QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta);
-
const QRectF &rect = r.normalized();
- const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f) - offs;
- const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f) - offs;
+ const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);
+ const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f);
if (s->flags.tx_noshear)
d->rasterizer->rasterizeLine(a, b, rect.height() / rect.width());
@@ -2739,13 +2724,12 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
return;
}
#endif
- const qreal offs = s->flags.antialiased ? qreal(0) : aliasedCoordinateDelta;
QPainterPath path;
path.addRect(r);
QTransform m = s->matrix;
s->matrix = QTransform(m.m11(), m.m12(), m.m13(),
m.m21(), m.m22(), m.m23(),
- m.m31() - offs, m.m32() - offs, m.m33());
+ m.m31(), m.m32(), m.m33());
fillPath(path, &d->image_filler_xform);
s->matrix = m;
} else {
@@ -3099,6 +3083,7 @@ void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
}
cache->populate(fontEngine, numGlyphs, glyphs, positions);
+ cache->fillInPendingGlyphs();
const QImage &image = cache->image();
int bpl = image.bytesPerLine();
@@ -3113,13 +3098,19 @@ void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
int margin = cache->glyphMargin();
- const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
+ bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
const uchar *bits = image.bits();
for (int i=0; i<numGlyphs; ++i) {
- const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]);
- int x = qFloor(positions[i].x + offs) + c.baseLineX - margin;
- int y = qFloor(positions[i].y + offs) - c.baseLineY - margin;
+
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions)
+ subPixelPosition = cache->subPixelPositionForX(positions[i].x);
+ QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
+ const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
+
+ int x = qFloor(positions[i].x) + c.baseLineX - margin;
+ int y = qFloor(positions[i].y) - c.baseLineY - margin;
// printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
// c.x, c.y,
@@ -3157,16 +3148,14 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti)
fe->setFontScale(matrix.m11());
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- const QFixed aliasDelta = QFixed::fromReal(aliasedCoordinateDelta);
-
for (int i=0; i<glyphs.size(); ++i) {
TOpenFontCharMetrics tmetrics;
const TUint8 *glyphBitmapBytes;
TSize glyphBitmapSize;
fe->getCharacterData(glyphs[i], tmetrics, glyphBitmapBytes, glyphBitmapSize);
const glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]);
- const int x = qFloor(positions[i].x + metrics.x + aliasDelta);
- const int y = qFloor(positions[i].y + metrics.y + aliasDelta);
+ const int x = qFloor(positions[i].x + metrics.x);
+ const int y = qFloor(positions[i].y + metrics.y);
alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight);
}
@@ -3380,7 +3369,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
#if defined(Q_WS_QWS)
if (fontEngine->type() == QFontEngine::Box) {
- fontEngine->draw(this, qFloor(p.x() + aliasedCoordinateDelta), qFloor(p.y() + aliasedCoordinateDelta), ti);
+ fontEngine->draw(this, qFloor(p.x()), qFloor(p.y()), ti);
return;
}
@@ -3389,7 +3378,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
|| (fontEngine->type() == QFontEngine::Proxy
&& !(static_cast<QProxyFontEngine *>(fontEngine)->drawAsOutline()))
)) {
- fontEngine->draw(this, qFloor(p.x() + aliasedCoordinateDelta), qFloor(p.y() + aliasedCoordinateDelta), ti);
+ fontEngine->draw(this, qFloor(p.x()), qFloor(p.y()), ti);
return;
}
#endif // Q_WS_QWS
@@ -3450,7 +3439,6 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
return;
}
- QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
FT_Face lockedFace = 0;
int depth;
@@ -3498,8 +3486,8 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
};
alphaPenBlt(glyph->data, pitch, depth,
- qFloor(positions[i].x + offs) + glyph->x,
- qFloor(positions[i].y + offs) - glyph->y,
+ qFloor(positions[i].x) + glyph->x,
+ qFloor(positions[i].y) - glyph->y,
glyph->width, glyph->height);
}
if (lockedFace)
@@ -3636,8 +3624,8 @@ void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)
int m11 = int(s->matrix.m11());
int m22 = int(s->matrix.m22());
- int dx = qFloor(s->matrix.dx() + aliasedCoordinateDelta);
- int dy = qFloor(s->matrix.dy() + aliasedCoordinateDelta);
+ int dx = qFloor(s->matrix.dx());
+ int dy = qFloor(s->matrix.dy());
for (int i=0; i<lineCount; ++i) {
int dashOffset = int(s->lastPen.dashOffset());
if (s->flags.int_xform) {
@@ -3741,7 +3729,7 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
for (int i=0; i<lineCount; ++i) {
int dashOffset = int(s->lastPen.dashOffset());
- QLineF line = (lines[i] * s->matrix).translated(aliasedCoordinateDelta, aliasedCoordinateDelta);
+ QLineF line = lines[i] * s->matrix;
const QRectF brect(QPointF(line.x1(), line.y1()),
QPointF(line.x2(), line.y2()));
ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 12be93e6d6..8f54a2e944 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -61,6 +61,8 @@
#include "qstyle.h"
#include "qthread.h"
#include "qvarlengtharray.h"
+#include "qstatictext.h"
+#include "qglyphs.h"
#include <private/qfontengine_p.h>
#include <private/qpaintengine_p.h>
@@ -70,8 +72,8 @@
#include <private/qwidget_p.h>
#include <private/qpaintengine_raster_p.h>
#include <private/qmath_p.h>
-#include <qstatictext.h>
#include <private/qstatictext_p.h>
+#include <private/qglyphs_p.h>
#include <private/qstylehelper_p.h>
QT_BEGIN_NAMESPACE
@@ -92,7 +94,7 @@ void qt_format_text(const QFont &font,
QPainter *painter);
static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
QTextCharFormat::UnderlineStyle underlineStyle,
- const QTextItem::RenderFlags flags, qreal width,
+ QTextItem::RenderFlags flags, qreal width,
const QTextCharFormat &charFormat);
// Helper function to calculate left most position, width and flags for decoration drawing
static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray,
@@ -162,6 +164,10 @@ static bool qt_painter_thread_test(int devType, const char *what, bool extraCond
#endif
break;
default:
+#ifdef Q_WS_X11
+ if (QApplication::testAttribute(Qt::AA_X11InitThreads))
+ return true;
+#endif
if (!extraCondition && QThread::currentThread() != qApp->thread()) {
qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
return false;
@@ -2701,6 +2707,61 @@ QPainterPath QPainter::clipPath() const
}
/*!
+ Returns the bounding rectangle of the current clip if there is a clip;
+ otherwise returns an empty rectangle. Note that the clip region is
+ given in logical coordinates.
+
+ The bounding rectangle is not guaranteed to be tight.
+
+ \sa setClipRect(), setClipPath(), setClipRegion()
+
+ \since 4.8
+ */
+
+QRectF QPainter::clipBoundingRect() const
+{
+ Q_D(const QPainter);
+
+ if (!d->engine) {
+ qWarning("QPainter::clipBoundingRect: Painter not active");
+ return QRectF();
+ }
+
+ // Accumulate the bounding box in device space. This is not 100%
+ // precise, but it fits within the guarantee and it is resonably
+ // fast.
+ QRectF bounds;
+ for (int i=0; i<d->state->clipInfo.size(); ++i) {
+ QRectF r;
+ const QPainterClipInfo &info = d->state->clipInfo.at(i);
+
+ if (info.clipType == QPainterClipInfo::RectClip)
+ r = info.rect;
+ else if (info.clipType == QPainterClipInfo::RegionClip)
+ r = info.region.boundingRect();
+ else
+ r = info.path.boundingRect();
+
+ r = info.matrix.mapRect(r);
+
+ if (i == 0)
+ bounds = r;
+ else if (info.operation == Qt::IntersectClip)
+ bounds &= r;
+ else if (info.operation == Qt::UniteClip)
+ bounds |= r;
+ }
+
+
+ // Map the rectangle back into logical space using the inverse
+ // matrix.
+ if (!d->txinv)
+ const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
+
+ return d->invMatrix.mapRect(bounds);
+}
+
+/*!
\fn void QPainter::setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
Enables clipping, and sets the clip region to the given \a
@@ -5256,7 +5317,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawPixmap()");
+ qt_painter_thread_test(d->device->devType(), "drawPixmap()", true);
#endif
if (d->extended) {
@@ -5326,7 +5387,7 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
if (!d->engine || pm.isNull())
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawPixmap()");
+ qt_painter_thread_test(d->device->devType(), "drawPixmap()", true);
#endif
qreal x = r.x();
@@ -5711,17 +5772,50 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR
d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
}
+/*!
+ Draws the glyphs represented by \a glyphs at \a position. The \a position gives the
+ edge of the baseline for the string of glyphs. The glyphs will be retrieved from the font
+ selected on \a glyphs and at offsets given by the positions in \a glyphs.
+
+ \since 4.8
+
+ \sa QGlyphs::setFont(), QGlyphs::setPositions(), QGlyphs::setGlyphIndexes()
+*/
+void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs)
+{
+ Q_D(QPainter);
+
+ QFont oldFont = d->state->font;
+ d->state->font = glyphs.font();
+
+ QVector<quint32> glyphIndexes = glyphs.glyphIndexes();
+ QVector<QPointF> glyphPositions = glyphs.positions();
+
+ int count = qMin(glyphIndexes.size(), glyphPositions.size());
+ QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
+ for (int i=0; i<count; ++i)
+ fixedPointPositions[i] = QFixedPoint::fromPointF(position + glyphPositions.at(i));
+
+ d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count);
+
+ d->state->font = oldFont;
+}
void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, const QPointF *positionArray,
int glyphCount)
{
+ QVarLengthArray<QFixedPoint, 128> positions(glyphCount);
+ for (int i=0; i<glyphCount; ++i)
+ positions[i] = QFixedPoint::fromPointF(positionArray[i]);
+
QPainterPrivate *painter_d = QPainterPrivate::get(painter);
- painter_d->drawGlyphs(glyphArray, positionArray, glyphCount);
+ painter_d->drawGlyphs(const_cast<quint32 *>(glyphArray), positions.data(), glyphCount);
}
-void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *positionArray,
- int glyphCount)
+void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount)
{
+ Q_Q(QPainter);
+
updateState(state);
QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common);
@@ -5736,12 +5830,27 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit
fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
}
- QVarLengthArray<QFixedPoint, 128> positions;
+ QFixed leftMost;
+ QFixed rightMost;
+ QFixed baseLine;
for (int i=0; i<glyphCount; ++i) {
- QFixedPoint fp = QFixedPoint::fromPointF(positionArray[i]);
- positions.append(fp);
+ glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
+ if (i == 0 || leftMost > positions[i].x)
+ leftMost = positions[i].x;
+
+ // We don't support glyphs that do not share a common baseline. If this turns out to
+ // be a relevant use case, then we need to find clusters of glyphs that share a baseline
+ // and do a drawTextItemDecorations call per cluster.
+ if (i == 0 || baseLine < positions[i].y)
+ baseLine = positions[i].y;
+
+ // We use the advance rather than the actual bounds to match the algorithm in drawText()
+ if (i == 0 || rightMost < positions[i].x + gm.xoff)
+ rightMost = positions[i].x + gm.xoff;
}
+ QFixed width = rightMost - leftMost;
+
if (extended != 0) {
QStaticTextItem staticTextItem;
staticTextItem.color = state->pen.color();
@@ -5749,7 +5858,7 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit
staticTextItem.fontEngine = fontEngine;
staticTextItem.numGlyphs = glyphCount;
staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray));
- staticTextItem.glyphPositions = positions.data();
+ staticTextItem.glyphPositions = positions;
extended->drawStaticTextItem(&staticTextItem);
} else {
@@ -5766,7 +5875,7 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit
textItem.glyphs.numGlyphs = glyphCount;
textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray));
- textItem.glyphs.offsets = positions.data();
+ textItem.glyphs.offsets = positions;
textItem.glyphs.advances_x = advances.data();
textItem.glyphs.advances_y = advances.data();
textItem.glyphs.justifications = glyphJustifications.data();
@@ -5774,6 +5883,21 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit
engine->drawTextItem(QPointF(0, 0), textItem);
}
+
+ QTextItemInt::RenderFlags flags;
+ if (state->font.underline())
+ flags |= QTextItemInt::Underline;
+ if (state->font.overline())
+ flags |= QTextItemInt::Overline;
+ if (state->font.strikeOut())
+ flags |= QTextItemInt::StrikeOut;
+
+ drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
+ fontEngine,
+ (state->font.underline()
+ ? QTextCharFormat::SingleUnderline
+ : QTextCharFormat::NoUnderline),
+ flags, width.toReal(), QTextCharFormat());
}
/*!
@@ -6309,7 +6433,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
QTextCharFormat::UnderlineStyle underlineStyle,
- const QTextItem::RenderFlags flags, qreal width,
+ QTextItem::RenderFlags flags, qreal width,
const QTextCharFormat &charFormat)
{
if (underlineStyle == QTextCharFormat::NoUnderline
@@ -6697,7 +6821,7 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()");
+ qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()", true);
#endif
qreal sw = pixmap.width();
@@ -7877,7 +8001,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
}
void qt_format_text(const QFont &fnt, const QRectF &_r,
int tf, const QTextOption *option, const QString& str, QRectF *brect,
- int tabstops, int *, int tabarraylen,
+ int tabstops, int *ta, int tabarraylen,
QPainter *painter)
{
@@ -7997,6 +8121,16 @@ start_lengthVariant:
engine.option = *option;
}
+ if (engine.option.tabStop() < 0 && tabstops > 0)
+ engine.option.setTabStop(tabstops);
+
+ if (engine.option.tabs().isEmpty() && ta) {
+ QList<qreal> tabs;
+ for (int i = 0; i < tabarraylen; i++)
+ tabs.append(qreal(ta[i]));
+ engine.option.setTabArray(tabs);
+ }
+
engine.option.setTextDirection(layout_direction);
if (tf & Qt::AlignJustify)
engine.option.setAlignment(Qt::AlignJustify);
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index edfb67ecb1..96305e3a4c 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -79,6 +79,7 @@ class QTextItem;
class QMatrix;
class QTransform;
class QStaticText;
+class QGlyphs;
class QPainterPrivateDeleter;
@@ -221,6 +222,8 @@ public:
void setClipping(bool enable);
bool hasClipping() const;
+ QRectF clipBoundingRect() const;
+
void save();
void restore();
@@ -396,6 +399,8 @@ public:
void setLayoutDirection(Qt::LayoutDirection direction);
Qt::LayoutDirection layoutDirection() const;
+ void drawGlyphs(const QPointF &position, const QGlyphs &glyphs);
+
void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText);
inline void drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText);
inline void drawStaticText(int left, int top, const QStaticText &staticText);
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 9362dbe80c..a61f5cae58 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -70,6 +70,7 @@ QT_BEGIN_NAMESPACE
class QPaintEngine;
class QEmulationPaintEngine;
class QPaintEngineEx;
+struct QFixedPoint;
struct QTLWExtra;
@@ -228,7 +229,7 @@ public:
void draw_helper(const QPainterPath &path, DrawOperation operation = StrokeAndFillDraw);
void drawStretchedGradient(const QPainterPath &path, DrawOperation operation);
void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation);
- void drawGlyphs(const quint32 *glyphArray, const QPointF *positionArray, int glyphCount);
+ void drawGlyphs(quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount);
void updateMatrix();
void updateInvMatrix();
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index 15d83b8bbb..9a7b60a3b2 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -95,6 +95,10 @@ public:
explicit QPainterPath(const QPointF &startPoint);
QPainterPath(const QPainterPath &other);
QPainterPath &operator=(const QPainterPath &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QPainterPath &operator=(QPainterPath &&other)
+ { qSwap(d_ptr, other.d_ptr); return *this; }
+#endif
~QPainterPath();
void closeSubpath();
diff --git a/src/gui/painting/qpen.h b/src/gui/painting/qpen.h
index aff70711c0..4006112dd7 100644
--- a/src/gui/painting/qpen.h
+++ b/src/gui/painting/qpen.h
@@ -74,6 +74,10 @@ public:
~QPen();
QPen &operator=(const QPen &pen);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QPen &operator=(QPen &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
Qt::PenStyle style() const;
void setStyle(Qt::PenStyle);
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index f8f8afb088..c92d8d5412 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -62,8 +62,8 @@ typedef int Q16Dot16;
#define SPAN_BUFFER_SIZE 256
-#define COORD_ROUNDING 1 // 0: round up, 1: round down
-#define COORD_OFFSET 32 // 26.6, 32 is half a pixel
+#define COORD_ROUNDING 0 // 0: round up, 1: round down
+#define COORD_OFFSET 0 // 26.6, 32 is half a pixel
class QSpanBuffer {
public:
@@ -718,7 +718,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
QPointF pa = a;
QPointF pb = b;
- QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
+ QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
if (squareCap)
offs += QPointF(offs.y(), offs.x());
const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs);
diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h
index bc4da285bb..2e4284444b 100644
--- a/src/gui/painting/qregion.h
+++ b/src/gui/painting/qregion.h
@@ -81,7 +81,10 @@ public:
QRegion(const QBitmap &bitmap);
~QRegion();
QRegion &operator=(const QRegion &);
-
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QRegion &operator=(QRegion &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
#ifdef QT3_SUPPORT
inline QT3_SUPPORT bool isNull() const { return isEmpty(); }
#endif
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 631a9cf8fa..e992bb2a59 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -69,8 +69,60 @@ static inline int qt_next_power_of_two(int v)
return v;
}
+int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const
+{
+ // Test 12 different subpixel positions since it factors into 3*4 so it gives
+ // the coverage we need.
+
+ QList<QImage> images;
+ for (int i=0; i<12; ++i) {
+ QImage img = textureMapForGlyph(glyph, QFixed::fromReal(i / 12.0));
+
+ if (images.isEmpty()) {
+ QPainterPath path;
+ QFixedPoint point;
+ m_current_fontengine->addGlyphsToPath(&glyph, &point, 1, &path, QTextItem::RenderFlags());
+
+ // Glyph is space, return 0 to indicate that we need to keep trying
+ if (path.isEmpty())
+ break;
+
+ images.append(img);
+ } else {
+ bool found = false;
+ for (int j=0; j<images.size(); ++j) {
+ if (images.at(j) == img) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ images.append(img);
+ }
+ }
+
+ return images.size();
+}
+
+QFixed QTextureGlyphCache::subPixelPositionForX(QFixed x) const
+{
+ if (m_subPixelPositionCount == 0)
+ return QFixed();
+
+ QFixed subPixelPosition;
+ if (x != 0) {
+ subPixelPosition = x - x.floor();
+ QFixed fraction = (subPixelPosition / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();
+
+ // Compensate for precision loss in fixed point to make sure we are always drawing at a subpixel position over
+ // the lower boundary for the selected rasterization by adding 1/64.
+ subPixelPosition = fraction / QFixed(m_subPixelPositionCount) + QFixed::fromReal(0.015625);
+ }
+ return subPixelPosition;
+}
+
void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
- const QFixedPoint *)
+ const QFixedPoint *positions)
{
#ifdef CACHE_DEBUG
printf("Populating with %d glyphs\n", numGlyphs);
@@ -81,15 +133,33 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
const int margin = glyphMargin();
const int paddingDoubled = glyphPadding() * 2;
- QHash<glyph_t, Coord> listItemCoordinates;
+ bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
+ if (m_subPixelPositionCount == 0) {
+ if (!supportsSubPixelPositions) {
+ m_subPixelPositionCount = 1;
+ } else {
+ int i = 0;
+ while (m_subPixelPositionCount == 0 && i < numGlyphs)
+ m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]);
+ }
+ }
+
+ QHash<GlyphAndSubPixelPosition, Coord> listItemCoordinates;
int rowHeight = 0;
// check each glyph for its metrics and get the required rowHeight.
for (int i=0; i < numGlyphs; ++i) {
const glyph_t glyph = glyphs[i];
- if (coords.contains(glyph))
+
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions) {
+ QFixed x = positions != 0 ? positions[i].x : QFixed();
+ subPixelPosition = subPixelPositionForX(x);
+ }
+
+ if (coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition)))
continue;
- if (listItemCoordinates.contains(glyph))
+ if (listItemCoordinates.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition)))
continue;
glyph_metrics_t metrics = fontEngine->boundingBox(glyph, m_transform);
@@ -119,18 +189,23 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
metrics.x.round().truncate(),
-metrics.y.truncate() }; // baseline for horizontal scripts
- listItemCoordinates.insert(glyph, c);
+ listItemCoordinates.insert(GlyphAndSubPixelPosition(glyph, subPixelPosition), c);
rowHeight = qMax(rowHeight, glyph_height);
}
if (listItemCoordinates.isEmpty())
return;
rowHeight += margin * 2 + paddingDoubled;
- if (isNull())
- createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, qt_next_power_of_two(rowHeight));
+
+ if (m_w == 0) {
+ if (fontEngine->maxCharWidth() <= QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH)
+ m_w = QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH;
+ else
+ m_w = qt_next_power_of_two(fontEngine->maxCharWidth());
+ }
// now actually use the coords and paint the wanted glyps into cache.
- QHash<glyph_t, Coord>::iterator iter = listItemCoordinates.begin();
+ QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = listItemCoordinates.begin();
while (iter != listItemCoordinates.end()) {
Coord c = iter.value();
@@ -142,29 +217,54 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
m_cy += m_currentRowHeight + paddingDoubled;
m_currentRowHeight = 0; // New row
}
- if (m_cy + c.h > m_h) {
- int new_height = m_h*2;
- while (new_height < m_cy + c.h)
- new_height *= 2;
- // if no room in the current texture - realloc a larger texture
- resizeTextureData(m_w, new_height);
- m_h = new_height;
- }
c.x = m_cx;
c.y = m_cy;
- fillTexture(c, iter.key());
coords.insert(iter.key(), c);
+ m_pendingGlyphs.insert(iter.key(), c);
m_cx += c.w + paddingDoubled;
++iter;
}
+}
+
+void QTextureGlyphCache::fillInPendingGlyphs()
+{
+ if (m_pendingGlyphs.isEmpty())
+ return;
+ int requiredHeight = 0;
+ {
+ QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = m_pendingGlyphs.begin();
+ while (iter != m_pendingGlyphs.end()) {
+ Coord c = iter.value();
+ requiredHeight = qMax(requiredHeight, c.y + c.h);
+ ++iter;
+ }
+ }
+
+ if (requiredHeight > m_h) {
+ if (isNull())
+ createCache(m_w, qt_next_power_of_two(requiredHeight));
+ else
+ resizeCache(m_w, qt_next_power_of_two(requiredHeight));
+ }
+
+ {
+ QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = m_pendingGlyphs.begin();
+ while (iter != m_pendingGlyphs.end()) {
+ GlyphAndSubPixelPosition key = iter.key();
+ fillTexture(iter.value(), key.glyph, key.subPixelPosition);
+
+ ++iter;
+ }
+ }
+ m_pendingGlyphs.clear();
}
-QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const
+QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const
{
#if defined(Q_WS_X11)
if (m_transform.type() > QTransform::TxTranslate) {
@@ -197,7 +297,7 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const
} else
#endif
if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
- return m_current_fontengine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform);
+ return m_current_fontengine->alphaRGBMapForGlyph(g, subPixelPosition, glyphMargin(), m_transform);
else
return m_current_fontengine->alphaMapForGlyph(g, m_transform);
@@ -243,9 +343,9 @@ int QImageTextureGlyphCache::glyphMargin() const
#endif
}
-void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g)
+void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subPixelPosition)
{
- QImage mask = textureMapForGlyph(g);
+ QImage mask = textureMapForGlyph(g, subPixelPosition);
#ifdef CACHE_DEBUG
printf("fillTexture of %dx%d at %d,%d in the cache of %dx%d\n", c.w, c.h, c.x, c.y, m_image.width(), m_image.height());
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index a818978915..413100341f 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -77,11 +77,24 @@ class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache
public:
QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
: QFontEngineGlyphCache(matrix, type), m_current_fontengine(0),
- m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0)
+ m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0), m_subPixelPositionCount(0)
{ }
virtual ~QTextureGlyphCache() { }
+ struct GlyphAndSubPixelPosition
+ {
+ GlyphAndSubPixelPosition(glyph_t g, QFixed spp) : glyph(g), subPixelPosition(spp) {}
+
+ bool operator==(const GlyphAndSubPixelPosition &other) const
+ {
+ return glyph == other.glyph && subPixelPosition == other.subPixelPosition;
+ }
+
+ glyph_t glyph;
+ QFixed subPixelPosition;
+ };
+
struct Coord {
int x;
int y;
@@ -94,13 +107,14 @@ public:
void populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
const QFixedPoint *positions);
+ void fillInPendingGlyphs();
virtual void createTextureData(int width, int height) = 0;
virtual void resizeTextureData(int width, int height) = 0;
virtual int glyphMargin() const { return 0; }
virtual int glyphPadding() const { return 0; }
- virtual void fillTexture(const Coord &coord, glyph_t glyph) = 0;
+ virtual void fillTexture(const Coord &coord, glyph_t glyph, QFixed subPixelPosition) = 0;
inline void createCache(int width, int height) {
m_w = width;
@@ -108,22 +122,40 @@ public:
createTextureData(width, height);
}
- inline bool isNull() const { return m_w <= 0 || m_h <= 0; }
+ inline void resizeCache(int width, int height)
+ {
+ resizeTextureData(width, height);
+ m_w = width;
+ m_h = height;
+ }
+
+ inline bool isNull() const { return m_h == 0; }
+
+ QHash<GlyphAndSubPixelPosition, Coord> coords;
- QHash<glyph_t, Coord> coords;
+ QImage textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const;
- QImage textureMapForGlyph(glyph_t g) const;
+ QFixed subPixelPositionForX(QFixed x) const;
protected:
+ int calculateSubPixelPositionCount(glyph_t) const;
+
QFontEngine *m_current_fontengine;
+ QHash<GlyphAndSubPixelPosition, Coord> m_pendingGlyphs;
int m_w; // image width
int m_h; // image height
int m_cx; // current x
int m_cy; // current y
int m_currentRowHeight; // Height of last row
+ int m_subPixelPositionCount; // Number of positions within a single pixel for this cache
};
+inline uint qHash(const QTextureGlyphCache::GlyphAndSubPixelPosition &g)
+{
+ return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt();
+}
+
class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache
{
@@ -133,7 +165,7 @@ public:
virtual int glyphMargin() const;
virtual void createTextureData(int width, int height);
virtual void resizeTextureData(int width, int height);
- virtual void fillTexture(const Coord &c, glyph_t glyph);
+ virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition);
inline const QImage &image() const { return m_image; }
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index eee6befe87..6a2cb1e605 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -248,10 +248,6 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
#ifdef Q_WS_MAC
-// qDebug() << "Flushing" << widget << rgn << offset;
-
-// d->image->image.save("flush.png");
-
Q_UNUSED(offset);
// Get a context for the widget.
#ifndef QT_MAC_USE_COCOA
@@ -282,20 +278,19 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
CGImageRef subImage = CGImageCreateWithImageInRect(image, area);
qt_mac_drawCGImage(context, &area, subImage);
+
CGImageRelease(subImage);
CGImageRelease(image);
-// CGSize size = { d->image->image.width(), d->image->image.height() };
-// CGLayerRef layer = CGLayerCreateWithContext(d->image->cg, size, 0);
-// CGPoint pt = { 0, 0 };
-// CGContextDrawLayerAtPoint(context, pt, layer);
-// CGLayerRelease(layer);
-
- // Restore context.
- CGContextRestoreGState(context);
#ifndef QT_MAC_USE_COCOA
QDEndCGContext(port, &context);
+#else
+ CGContextFlush(context);
#endif
+
+ // Restore context.
+ CGContextRestoreGState(context);
+
#endif // Q_WS_MAC
#ifdef Q_OS_SYMBIAN
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index 8bac1f5f69..d4dcf7dd07 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -77,7 +77,8 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget)
}
// We create empty CFbsBitmap here -> it will be resized in setGeometry
- CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
+ CFbsBitmap *bitmap = new CFbsBitmap; // CBase derived object needs check on new
+ Q_CHECK_PTR(bitmap);
qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType);
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index 306219d01f..e280a5112d 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -3763,6 +3763,7 @@ int QCleanlooksStyle::pixelMetric(PixelMetric metric, const QStyleOption *option
break;
case PM_MenuBarItemSpacing:
ret = 6;
+ break;
case PM_MenuBarHMargin:
ret = 0;
break;
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 671a888501..556e0f303e 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -1642,7 +1642,7 @@ bool QMacStylePrivate::eventFilter(QObject *o, QEvent *e)
case QEvent::FocusOut:
case QEvent::Show:
case QEvent::WindowActivate: {
- QList<QPushButton *> list = qFindChildren<QPushButton *>(btn->window());
+ QList<QPushButton *> list = btn->window()->findChildren<QPushButton *>();
for (int i = 0; i < list.size(); ++i) {
QPushButton *pBtn = list.at(i);
if ((e->type() == QEvent::FocusOut
@@ -5538,6 +5538,57 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
// hack to work around horrible sizeHint() code in QAbstractSpinBox
sz.setHeight(sz.height() - 3);
break;
+ case QStyle::CT_TabWidget:
+ // the size between the pane and the "contentsRect" (+4,+4)
+ // (the "contentsRect" is on the inside of the pane)
+ sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
+ /**
+ This is supposed to show the relationship between the tabBar and
+ the stack widget of a QTabWidget.
+ Unfortunately ascii is not a good way of representing graphics.....
+ PS: The '=' line is the painted frame.
+
+ top ---+
+ |
+ |
+ |
+ | vvv just outside the painted frame is the "pane"
+ - -|- - - - - - - - - - <-+
+ TAB BAR +=====^============ | +2 pixels
+ - - -|- - -|- - - - - - - <-+
+ | | ^ ^^^ just inside the painted frame is the "contentsRect"
+ | | |
+ | overlap |
+ | | |
+ bottom ------+ <-+ +14 pixels
+ |
+ v
+ ------------------------------ <- top of stack widget
+
+
+ To summarize:
+ * 2 is the distance between the pane and the contentsRect
+ * The 14 and the 1's are the distance from the contentsRect to the stack widget.
+ (same value as used in SE_TabWidgetTabContents)
+ * overlap is how much the pane should overlap the tab bar
+ */
+ // then add the size between the stackwidget and the "contentsRect"
+
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QSize extra(0,0);
+ const int overlap = pixelMetric(PM_TabBarBaseOverlap, opt, widget);
+ const int gapBetweenTabbarAndStackWidget = 2 + 14 - overlap;
+
+ if (getTabDirection(twf->shape) == kThemeTabNorth || getTabDirection(twf->shape) == kThemeTabSouth) {
+ extra = QSize(2, gapBetweenTabbarAndStackWidget + 1);
+ } else {
+ extra = QSize(gapBetweenTabbarAndStackWidget + 1, 2);
+ }
+ sz+= extra;
+ }
+
+ break;
case QStyle::CT_TabBarTab:
if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
const QAquaWidgetSize AquaSize = d->aquaSizeConstrain(opt, widget);
diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp
index 20d9bd9b35..4690a71cb1 100644
--- a/src/gui/styles/qplastiquestyle.cpp
+++ b/src/gui/styles/qplastiquestyle.cpp
@@ -1054,7 +1054,7 @@ void QPlastiqueStylePrivate::drawPartialFrame(QPainter *painter, const QStyleOpt
bool reverse = option->direction == Qt::RightToLeft;
QStyleOptionFrame frameOpt;
#ifndef QT_NO_LINEEDIT
- if (QLineEdit *lineedit = qFindChild<QLineEdit *>(widget))
+ if (QLineEdit *lineedit = widget->findChild<QLineEdit *>())
frameOpt.initFrom(lineedit);
#else
Q_UNUSED(widget)
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 5996032b32..9116a1e061 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -1427,7 +1427,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
bool isScrollBarVisible = false;
int scrollBarWidth = 0;
- QList<QScrollBar *> scrollBars = qFindChildren<QScrollBar *>(widget);
+ QList<QScrollBar *> scrollBars = widget->findChildren<QScrollBar *>();
for (int i = 0; i < scrollBars.size(); ++i) {
QScrollBar *scrollBar = scrollBars.at(i);
if (scrollBar && scrollBar->orientation() == Qt::Vertical) {
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 92e2c816e6..4be439d6d0 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -2342,7 +2342,7 @@ static QWidget *embeddedWidget(QWidget *w)
#ifndef QT_NO_SPINBOX
if (QAbstractSpinBox *sb = qobject_cast<QAbstractSpinBox *>(w))
- return qFindChild<QLineEdit *>(sb);
+ return sb->findChild<QLineEdit *>();
#endif
#ifndef QT_NO_SCROLLAREA
@@ -2583,7 +2583,7 @@ void QStyleSheetStyle::unsetPalette(QWidget *w)
}
QVariant oldFont = w->property("_q_styleSheetWidgetFont");
if (oldFont.isValid()) {
- w->setFont(qVariantValue<QFont>(oldFont));
+ w->setFont(qvariant_cast<QFont>(oldFont));
}
if (autoFillDisabledWidgets->contains(w)) {
embeddedWidget(w)->setAutoFillBackground(true);
@@ -2795,7 +2795,7 @@ void QStyleSheetStyle::polish(QPalette &pal)
void QStyleSheetStyle::repolish(QWidget *w)
{
- QList<const QWidget *> children = qFindChildren<const QWidget *>(w, QString());
+ QList<const QWidget *> children = w->findChildren<const QWidget *>(QString());
children.append(w);
styleSheetCache->remove(w);
updateWidgets(children);
@@ -3048,6 +3048,13 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
titleRule.configurePalette(&pal, QPalette::WindowText, QPalette::Window);
drawItemText(p, labelRect, alignment, pal, gb->state & State_Enabled,
gb->text, QPalette::WindowText);
+
+ if (gb->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*gb);
+ fropt.rect = labelRect;
+ drawPrimitive(PE_FrameFocusRect, &fropt, p, w);
+ }
}
return;
@@ -5074,7 +5081,7 @@ QIcon QStyleSheetStyle::standardIconImplementation(StandardPixmap standardIcon,
if (!s.isEmpty()) {
QRenderRule rule = renderRule(w, opt);
if (rule.hasStyleHint(s))
- return qVariantValue<QIcon>(rule.styleHint(s));
+ return qvariant_cast<QIcon>(rule.styleHint(s));
}
return baseStyle()->standardIcon(standardIcon, opt, w);
}
@@ -5092,7 +5099,7 @@ QPixmap QStyleSheetStyle::standardPixmap(StandardPixmap standardPixmap, const QS
if (!s.isEmpty()) {
QRenderRule rule = renderRule(w, opt);
if (rule.hasStyleHint(s)) {
- QIcon icon = qVariantValue<QIcon>(rule.styleHint(s));
+ QIcon icon = qvariant_cast<QIcon>(rule.styleHint(s));
return icon.pixmap(16, 16); // ###: unhard-code this if someone complains
}
}
@@ -5186,7 +5193,7 @@ int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWi
case SH_ComboBox_PopupFrameStyle:
#ifndef QT_NO_COMBOBOX
if (qobject_cast<const QComboBox *>(w)) {
- QAbstractItemView *view = qFindChild<QAbstractItemView *>(w);
+ QAbstractItemView *view = w->findChild<QAbstractItemView *>();
if (view) {
view->ensurePolished();
QRenderRule subRule = renderRule(view, PseudoElement_None);
diff --git a/src/gui/styles/qwindowscestyle.cpp b/src/gui/styles/qwindowscestyle.cpp
index b027005604..bd7246ab15 100644
--- a/src/gui/styles/qwindowscestyle.cpp
+++ b/src/gui/styles/qwindowscestyle.cpp
@@ -2294,6 +2294,7 @@ int QWindowsCEStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QW
break;
case SH_EtchDisabledText:
ret = false;
+ break;
case SH_RequestSoftwareInputPanel:
ret = RSIP_OnMouseClick;
break;
diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp
index 720dd6d2d8..d994b9b59d 100644
--- a/src/gui/styles/qwindowsstyle.cpp
+++ b/src/gui/styles/qwindowsstyle.cpp
@@ -175,7 +175,7 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
widget = widget->window();
// Alt has been pressed - find all widgets that care
- QList<QWidget *> l = qFindChildren<QWidget *>(widget);
+ QList<QWidget *> l = widget->findChildren<QWidget *>();
for (int pos=0 ; pos < l.size() ; ++pos) {
QWidget *w = l.at(pos);
if (w->isWindow() || !w->isVisible() ||
@@ -198,7 +198,7 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
// Update state and repaint the menu bars.
d->alt_down = false;
#ifndef QT_NO_MENUBAR
- QList<QMenuBar *> l = qFindChildren<QMenuBar *>(widget);
+ QList<QMenuBar *> l = widget->findChildren<QMenuBar *>();
for (int i = 0; i < l.size(); ++i)
l.at(i)->update();
#endif
@@ -1160,7 +1160,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
if (!menuBar && qobject_cast<const QMenu *>(widget)) {
QWidget *w = QApplication::activeWindow();
if (w && w != widget)
- menuBar = qFindChild<QMenuBar *>(w);
+ menuBar = w->findChild<QMenuBar *>();
}
// If we paint a menu bar draw underlines if is in the keyboardState
if (menuBar) {
diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp
index 58542e5252..bed5b0999d 100644
--- a/src/gui/styles/qwindowsvistastyle.cpp
+++ b/src/gui/styles/qwindowsvistastyle.cpp
@@ -842,10 +842,10 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
const QDialogButtonBox *buttonBox = 0;
if (qobject_cast<const QMessageBox *> (widget))
- buttonBox = qFindChild<const QDialogButtonBox *>(widget,QLatin1String("qt_msgbox_buttonbox"));
+ buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
#ifndef QT_NO_INPUTDIALOG
else if (qobject_cast<const QInputDialog *> (widget))
- buttonBox = qFindChild<const QDialogButtonBox *>(widget,QLatin1String("qt_inputdlg_buttonbox"));
+ buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
#endif // QT_NO_INPUTDIALOG
if (buttonBox) {
@@ -2396,14 +2396,14 @@ void QWindowsVistaStyle::polish(QWidget *widget)
}
} else if (qobject_cast<QMessageBox *> (widget)) {
widget->setAttribute(Qt::WA_StyledBackground);
- QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_msgbox_buttonbox"));
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
if (buttonBox)
buttonBox->setContentsMargins(0, 9, 0, 0);
}
#ifndef QT_NO_INPUTDIALOG
else if (qobject_cast<QInputDialog *> (widget)) {
widget->setAttribute(Qt::WA_StyledBackground);
- QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_inputdlg_buttonbox"));
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
if (buttonBox)
buttonBox->setContentsMargins(0, 9, 0, 0);
}
@@ -2435,14 +2435,14 @@ void QWindowsVistaStyle::unpolish(QWidget *widget)
widget->setAttribute(Qt::WA_Hover, false);
else if (qobject_cast<QMessageBox *> (widget)) {
widget->setAttribute(Qt::WA_StyledBackground, false);
- QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_msgbox_buttonbox"));
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
if (buttonBox)
buttonBox->setContentsMargins(0, 0, 0, 0);
}
#ifndef QT_NO_INPUTDIALOG
else if (qobject_cast<QInputDialog *> (widget)) {
widget->setAttribute(Qt::WA_StyledBackground, false);
- QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_inputdlg_buttonbox"));
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
if (buttonBox)
buttonBox->setContentsMargins(0, 0, 0, 0);
}
diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp
index d36011c9ca..7ab1218723 100644
--- a/src/gui/styles/qwindowsxpstyle.cpp
+++ b/src/gui/styles/qwindowsxpstyle.cpp
@@ -4054,7 +4054,7 @@ void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h)
bufferPos += sprintf(bufferPos, "\n};\n\n");
printf(bufferDump);
- delete bufferDump;
+ delete[] bufferDump;
++pCount;
}
}
diff --git a/src/gui/symbian/qsymbianevent.cpp b/src/gui/symbian/qsymbianevent.cpp
index c3414138fc..a7cfeef800 100644
--- a/src/gui/symbian/qsymbianevent.cpp
+++ b/src/gui/symbian/qsymbianevent.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include "qsymbianevent.h"
+#include <qdebug.h>
+
+#include <w32std.h>
QT_BEGIN_NAMESPACE
@@ -140,4 +143,34 @@ int QSymbianEvent::resourceChangeType() const
return (m_type == ResourceChangeEvent) ? m_eventValue : 0;
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QSymbianEvent *o)
+{
+ if (!o) {
+ dbg << "QSymbianEvent(0x0)";
+ return dbg;
+ }
+ dbg.nospace() << "QSymbianEvent(";
+ switch (o->type()) {
+ case QSymbianEvent::InvalidEvent:
+ dbg << "InvalidEvent";
+ break;
+ case QSymbianEvent::WindowServerEvent:
+ dbg << "WindowServerEvent, Type = " << o->windowServerEvent()->Type();
+ break;
+ case QSymbianEvent::CommandEvent:
+ dbg << "CommandEvent, command = " << o->command();
+ break;
+ case QSymbianEvent::ResourceChangeEvent:
+ dbg << "ResourceChangeEvent, resourceChangeType = " << o->resourceChangeType();
+ break;
+ default:
+ dbg << "Unknown event type";
+ break;
+ }
+ dbg << ")";
+ return dbg.space();
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/gui/symbian/qsymbianevent.h b/src/gui/symbian/qsymbianevent.h
index 5cad654c7d..4c9ae65e2e 100644
--- a/src/gui/symbian/qsymbianevent.h
+++ b/src/gui/symbian/qsymbianevent.h
@@ -95,6 +95,10 @@ inline bool QSymbianEvent::isValid() const
return m_type != InvalidEvent;
}
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QSymbianEvent *o);
+#endif
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index b3d25267ac..dafc8e762b 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -68,6 +68,8 @@ static const QCssKnownValue properties[NumProperties - 1] = {
{ "-qt-background-role", QtBackgroundRole },
{ "-qt-block-indent", QtBlockIndent },
{ "-qt-list-indent", QtListIndent },
+ { "-qt-list-number-prefix", QtListNumberPrefix },
+ { "-qt-list-number-suffix", QtListNumberSuffix },
{ "-qt-paragraph-type", QtParagraphType },
{ "-qt-style-features", QtStyleFeatures },
{ "-qt-table-type", QtTableType },
@@ -403,7 +405,7 @@ int ValueExtractor::lengthValue(const Declaration &decl)
if (decl.d->values.count() < 1)
return 0;
LengthData data = lengthValue(decl.d->values.at(0));
- decl.d->parsed = qVariantFromValue<LengthData>(data);
+ decl.d->parsed = QVariant::fromValue<LengthData>(data);
return lengthValueFromData(data,f);
}
@@ -435,7 +437,7 @@ void ValueExtractor::lengthValues(const Declaration &decl, int *m)
QList<QVariant> v;
for (i = 0; i < 4; i++) {
- v += qVariantFromValue<LengthData>(datas[i]);
+ v += QVariant::fromValue<LengthData>(datas[i]);
m[i] = lengthValueFromData(datas[i], f);
}
decl.d->parsed = v;
@@ -541,7 +543,7 @@ QSize ValueExtractor::sizeValue(const Declaration &decl)
else
x[1] = x[0];
QList<QVariant> v;
- v << qVariantFromValue<LengthData>(x[0]) << qVariantFromValue<LengthData>(x[1]);
+ v << QVariant::fromValue<LengthData>(x[0]) << qVariantFromValue<LengthData>(x[1]);
decl.d->parsed = v;
return QSize(lengthValueFromData(x[0], f), lengthValueFromData(x[1], f));
}
@@ -916,7 +918,7 @@ void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::Bord
data.width = lengthValue(decl.d->values.at(i));
*width = lengthValueFromData(data.width, f);
if (++i >= decl.d->values.count()) {
- decl.d->parsed = qVariantFromValue<BorderData>(data);
+ decl.d->parsed = QVariant::fromValue<BorderData>(data);
return;
}
}
@@ -925,7 +927,7 @@ void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::Bord
if (data.style != BorderStyle_Unknown) {
*style = data.style;
if (++i >= decl.d->values.count()) {
- decl.d->parsed = qVariantFromValue<BorderData>(data);
+ decl.d->parsed = QVariant::fromValue<BorderData>(data);
return;
}
} else {
@@ -935,7 +937,7 @@ void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::Bord
data.color = parseBrushValue(decl.d->values.at(i), pal);
*color = brushFromData(data.color, pal);
if (data.color.type != BrushData::DependsOnThePalette)
- decl.d->parsed = qVariantFromValue<BorderData>(data);
+ decl.d->parsed = QVariant::fromValue<BorderData>(data);
}
static void parseShorthandBackgroundProperty(const QVector<Value> &values, BrushData *brush, QString *image, Repeat *repeat, Qt::Alignment *alignment, const QPalette &pal)
@@ -1032,16 +1034,8 @@ bool ValueExtractor::extractBackground(QBrush *brush, QString *image, Repeat *re
parseShorthandBackgroundProperty(decl.d->values, &brushData, image, repeat, alignment, pal);
*brush = brushFromData(brushData, pal);
if (brushData.type != BrushData::DependsOnThePalette) {
-#if defined Q_CC_MSVC && _MSC_VER <= 1300
- BackgroundData data;
- data.brush = brushData;
- data.image = *image;
- data.repeat = *repeat;
- data.alignment = *alignment;
-#else
BackgroundData data = { brushData, *image, *repeat, *alignment };
-#endif
- decl.d->parsed = qVariantFromValue<BackgroundData>(data);
+ decl.d->parsed = QVariant::fromValue<BackgroundData>(data);
}
}
break;
@@ -1319,10 +1313,10 @@ QColor Declaration::colorValue(const QPalette &pal) const
ColorData color = parseColorValue(d->values.at(0));
if(color.type == ColorData::Role) {
- d->parsed = qVariantFromValue<int>(color.role);
+ d->parsed = QVariant::fromValue<int>(color.role);
return pal.color((QPalette::ColorRole)(color.role));
} else {
- d->parsed = qVariantFromValue<QColor>(color.color);
+ d->parsed = QVariant::fromValue<QColor>(color.color);
return color.color;
}
}
@@ -1342,11 +1336,11 @@ QBrush Declaration::brushValue(const QPalette &pal) const
BrushData data = parseBrushValue(d->values.at(0), pal);
if(data.type == BrushData::Role) {
- d->parsed = qVariantFromValue<int>(data.role);
+ d->parsed = QVariant::fromValue<int>(data.role);
return pal.color((QPalette::ColorRole)(data.role));
} else {
if (data.type != BrushData::DependsOnThePalette)
- d->parsed = qVariantFromValue<QBrush>(data.brush);
+ d->parsed = QVariant::fromValue<QBrush>(data.brush);
return data.brush;
}
}
@@ -1376,11 +1370,11 @@ void Declaration::brushValues(QBrush *c, const QPalette &pal) const
continue;
BrushData data = parseBrushValue(d->values.at(i), pal);
if(data.type == BrushData::Role) {
- v += qVariantFromValue<int>(data.role);
+ v += QVariant::fromValue<int>(data.role);
c[i] = pal.color((QPalette::ColorRole)(data.role));
} else {
if (data.type != BrushData::DependsOnThePalette) {
- v += qVariantFromValue<QBrush>(data.brush);
+ v += QVariant::fromValue<QBrush>(data.brush);
} else {
v += QVariant();
}
@@ -1453,7 +1447,7 @@ QSize Declaration::sizeValue() const
else
x[1] = x[0];
QSize size(x[0], x[1]);
- d->parsed = qVariantFromValue<QSize>(size);
+ d->parsed = QVariant::fromValue<QSize>(size);
return size;
}
@@ -1475,7 +1469,7 @@ QRect Declaration::rectValue() const
if (args.count() != 4)
return QRect();
QRect rect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt());
- d->parsed = qVariantFromValue<QRect>(rect);
+ d->parsed = QVariant::fromValue<QRect>(rect);
return rect;
}
@@ -1496,10 +1490,10 @@ void Declaration::colorValues(QColor *c, const QPalette &pal) const
for (i = 0; i < qMin(d->values.count(), 4); i++) {
ColorData color = parseColorValue(d->values.at(i));
if(color.type == ColorData::Role) {
- v += qVariantFromValue<int>(color.role);
+ v += QVariant::fromValue<int>(color.role);
c[i] = pal.color((QPalette::ColorRole)(color.role));
} else {
- v += qVariantFromValue<QColor>(color.color);
+ v += QVariant::fromValue<QColor>(color.color);
c[i] = color.color;
}
}
@@ -1691,7 +1685,7 @@ QIcon Declaration::iconValue() const
i++;
}
- d->parsed = qVariantFromValue<QIcon>(icon);
+ d->parsed = QVariant::fromValue<QIcon>(icon);
return icon;
}
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index 138d506c44..ca9688ef6a 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -178,6 +178,8 @@ enum Property {
OutlineBottomRightRadius,
FontVariant,
TextTransform,
+ QtListNumberPrefix,
+ QtListNumberSuffix,
NumProperties
};
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 2cc41e1da0..d6f4dc51a6 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -226,7 +226,10 @@ public:
bool operator<(const QFont &) const;
operator QVariant() const;
bool isCopyOf(const QFont &) const;
-
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QFont &operator=(QFont &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
#ifdef Q_WS_WIN
HFONT handle() const;
@@ -315,6 +318,7 @@ private:
friend class QPainterReplayer;
friend class QPaintBufferEngine;
friend class QCommandLinkButtonPrivate;
+ friend class QFontEngine;
#ifndef QT_NO_DATASTREAM
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QFont &);
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 470c10920c..646a8b8601 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -192,6 +192,11 @@ public:
QFont smallCapsFont() const { return QFont(smallCapsFontPrivate()); }
QFontPrivate *smallCapsFontPrivate() const;
+ static QFontPrivate *get(const QFont &font)
+ {
+ return font.d.data();
+ }
+
void resolve(uint mask, const QFontPrivate *other);
private:
QFontPrivate &operator=(const QFontPrivate &) { return *this; }
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index e6c36a4862..2b2663849e 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -75,10 +75,6 @@
# define FM_DEBUG if (false) qDebug
#endif
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
-# define for if(0){}else for
-#endif
-
QT_BEGIN_NAMESPACE
#define SMOOTH_SCALABLE 0xffff
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
index 5a9fc35710..712bdb4205 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/gui/text/qfontdatabase_mac.cpp
@@ -293,8 +293,12 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
// previous versions
family_list << QApplication::font().defaultFamily();
+#if defined(QT_MAC_USE_COCOA)
+ QCFString fontName = NULL, familyName = NULL;
+#else
ATSFontFamilyRef familyRef = 0;
ATSFontRef fontRef = 0;
+#endif
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
@@ -304,26 +308,20 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
for (int k = 0; k < db->count; ++k) {
if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
QByteArray family_name = db->families[k]->name.toUtf8();
+#if defined(QT_MAC_USE_COCOA)
+ QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
+ if (ctFont) {
+ fontName = CTFontCopyFullName(ctFont);
+ familyName = CTFontCopyFamilyName(ctFont);
+ goto FamilyFound;
+ }
+#else
familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
if (familyRef) {
fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
goto FamilyFound;
- } else {
-#if defined(QT_MAC_USE_COCOA)
- // ATS and CT disagrees on what the family name should be,
- // use CT to look up the font if ATS fails.
- QCFString familyName = QString::fromAscii(family_name);
- QCFType<CTFontRef> CTfontRef = CTFontCreateWithName(familyName, 12, NULL);
- QCFType<CTFontDescriptorRef> fontDescriptor = CTFontCopyFontDescriptor(CTfontRef);
- QCFString displayName = (CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontDisplayNameAttribute);
-
- familyRef = ATSFontFamilyFindFromName(displayName, kATSOptionFlagsDefault);
- if (familyRef) {
- fontRef = ATSFontFindFromName(displayName, kATSOptionFlagsDefault);
- goto FamilyFound;
- }
-#endif
}
+#endif
}
}
}
@@ -331,92 +329,18 @@ FamilyFound:
//fill in the engine's font definition
QFontDef fontDef = d->request; //copy..
if(fontDef.pointSize < 0)
- fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
+ fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
else
- fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
-#if 0
- ItemCount name_count;
- if(ATSUCountFontNames(fontID, &name_count) == noErr && name_count) {
- ItemCount actualName_size;
- if(ATSUGetIndFontName(fontID, 0, 0, 0, &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) {
- QByteArray actualName(actualName_size);
- if(ATSUGetIndFontName(fontID, 0, actualName_size, actualName.data(), &actualName_size, 0, 0, 0, 0) == noErr && actualName_size)
- fontDef.family = QString::fromUtf8(actualName);
- }
- }
-#else
- {
- QCFString actualName;
- if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
- fontDef.family = actualName;
- }
-#endif
+ fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
#ifdef QT_MAC_USE_COCOA
- QFontEngine *engine = new QCoreTextFontEngineMulti(familyRef, fontRef, fontDef, d->kerning);
-#elif 1
- QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning);
+ fontDef.family = familyName;
+ QFontEngine *engine = new QCoreTextFontEngineMulti(fontName, fontDef, d->kerning);
#else
- ATSFontFamilyRef atsFamily = familyRef;
- ATSFontFamilyRef atsFontRef = fontRef;
-
- FMFont fontID;
- FMFontFamily fmFamily;
- FMFontStyle fntStyle = 0;
- fmFamily = FMGetFontFamilyFromATSFontFamilyRef(atsFamily);
- if (fmFamily == kInvalidFontFamily) {
- // Use the ATSFont then...
- fontID = FMGetFontFromATSFontRef(atsFontRef);
- } else {
- if (fontDef.weight >= QFont::Bold)
- fntStyle |= ::bold;
- if (fontDef.style != QFont::StyleNormal)
- fntStyle |= ::italic;
-
- FMFontStyle intrinsicStyle;
- FMFont fnt = 0;
- if (FMGetFontFromFontFamilyInstance(fmFamily, fntStyle, &fnt, &intrinsicStyle) == noErr)
- fontID = FMGetATSFontRefFromFont(fnt);
- }
-
- OSStatus status;
-
- const int maxAttributeCount = 5;
- ATSUAttributeTag tags[maxAttributeCount + 1];
- ByteCount sizes[maxAttributeCount + 1];
- ATSUAttributeValuePtr values[maxAttributeCount + 1];
- int attributeCount = 0;
-
- Fixed size = FixRatio(fontDef.pixelSize, 1);
- tags[attributeCount] = kATSUSizeTag;
- sizes[attributeCount] = sizeof(size);
- values[attributeCount] = &size;
- ++attributeCount;
-
- tags[attributeCount] = kATSUFontTag;
- sizes[attributeCount] = sizeof(fontID);
- values[attributeCount] = &fontID;
- ++attributeCount;
-
- CGAffineTransform transform = CGAffineTransformIdentity;
- if (fontDef.stretch != 100) {
- transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
- tags[attributeCount] = kATSUFontMatrixTag;
- sizes[attributeCount] = sizeof(transform);
- values[attributeCount] = &transform;
- ++attributeCount;
- }
-
- ATSUStyle style;
- status = ATSUCreateStyle(&style);
- Q_ASSERT(status == noErr);
-
- Q_ASSERT(attributeCount < maxAttributeCount + 1);
- status = ATSUSetAttributes(style, attributeCount, tags, sizes, values);
- Q_ASSERT(status == noErr);
-
- QFontEngine *engine = new QFontEngineMac(style, fontID, fontDef, /*multiEngine*/ 0);
- ATSUDisposeStyle(style);
+ QCFString actualName;
+ if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
+ fontDef.family = actualName;
+ QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning);
#endif
d->engineData->engine = engine;
engine->ref.ref(); //a ref for the engineData->engine
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 0dfd295514..70b7d65fab 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -185,10 +185,6 @@ QFontEngine::QFontEngine()
QFontEngine::~QFontEngine()
{
- for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(),
- end = m_glyphCaches.constEnd(); it != end; ++it) {
- delete it->cache;
- }
m_glyphCaches.clear();
qHBFreeFace(hbFace);
}
@@ -242,6 +238,24 @@ glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix
return metrics;
}
+QFont QFontEngine::createExplicitFont() const
+{
+ return createExplicitFontWithName(fontDef.family);
+}
+
+QFont QFontEngine::createExplicitFontWithName(const QString &familyName) const
+{
+ QFont font(familyName);
+ font.setStyleStrategy(QFont::NoFontMerging);
+ font.setWeight(fontDef.weight);
+ font.setItalic(fontDef.style == QFont::StyleItalic);
+ if (fontDef.pointSize < 0)
+ font.setPixelSize(fontDef.pixelSize);
+ else
+ font.setPointSizeF(fontDef.pointSize);
+ return font;
+}
+
QFixed QFontEngine::xHeight() const
{
QGlyphLayoutArray<8> glyphs;
@@ -602,7 +616,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &t)
return i;
}
-QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int /* margin */, const QTransform &t)
+QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, int /* margin */, const QTransform &t)
{
QImage alphaMask = alphaMapForGlyph(glyph, t);
QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32);
@@ -716,14 +730,16 @@ void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data)
{
Q_ASSERT(data);
- GlyphCacheEntry entry = { key, data };
+ GlyphCacheEntry entry;
+ entry.context = key;
+ entry.cache = data;
if (m_glyphCaches.contains(entry))
return;
// Limit the glyph caches to 4. This covers all 90 degree rotations and limits
// memory use when there is continuous or random rotation
if (m_glyphCaches.size() == 4)
- delete m_glyphCaches.takeLast().cache;
+ m_glyphCaches.removeLast();
m_glyphCaches.push_front(entry);
@@ -732,7 +748,7 @@ void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data)
QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const
{
for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) {
- QFontEngineGlyphCache *c = it->cache;
+ QFontEngineGlyphCache *c = it->cache.data();
if (key == it->context
&& type == c->cacheType()
&& qtransform_equals_no_translate(c->m_transform, transform)) {
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index a9b25f552d..5e86b37a6b 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -763,9 +763,18 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph
return g;
int load_flags = FT_LOAD_DEFAULT | default_load_flags;
+ int load_target = default_hint_style == HintLight
+ ? FT_LOAD_TARGET_LIGHT
+ : FT_LOAD_TARGET_NORMAL;
+
if (set->outline_drawing)
load_flags = FT_LOAD_NO_BITMAP;
+ if (default_hint_style == HintNone)
+ load_flags |= FT_LOAD_NO_HINTING;
+ else
+ load_flags |= load_target;
+
// apply our matrix to this, but note that the metrics will not be affected by this.
FT_Face face = lockFace();
FT_Matrix matrix = this->matrix;
@@ -1869,10 +1878,10 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g)
return img;
}
-QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransform &t)
+QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, int margin, const QTransform &t)
{
if (t.type() > QTransform::TxTranslate)
- return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
+ return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, margin, t);
lockFace();
@@ -1881,7 +1890,7 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransfor
Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
if (!glyph) {
unlockFace();
- return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
+ return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, margin, t);
}
QImage img(glyph->width, glyph->height, QImage::Format_RGB32);
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 2f05a8b981..72f7d9f855 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -241,7 +241,7 @@ private:
virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const;
virtual QImage alphaMapForGlyph(glyph_t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual void removeGlyphFromCache(glyph_t glyph);
virtual int glyphCount() const;
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index bdf3848b71..6e524f61cb 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -143,7 +143,7 @@ void qmacfontengine_gamma_correct(QImage *image)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
+QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
this->fontDef = fontDef;
@@ -159,9 +159,6 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con
break;
}
- QCFString name;
- ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
-
transform = CGAffineTransformIdentity;
if (fontDef.stretch != 100) {
transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
@@ -422,8 +419,7 @@ QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def,
synthesisFlags = 0;
ctfont = font;
CFRetain(ctfont);
- ATSFontRef atsfont = CTFontGetPlatformFont(ctfont, 0);
- cgFont = CGFontCreateWithPlatformFont(&atsfont);
+ cgFont = CTFontCopyGraphicsFont(ctfont, NULL);
CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) {
synthesisFlags |= SynthesizedBold;
@@ -443,8 +439,8 @@ QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def,
QCoreTextFontEngine::~QCoreTextFontEngine()
{
- CFRelease(ctfont);
CFRelease(cgFont);
+ CFRelease(ctfont);
}
bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const
@@ -657,7 +653,13 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
}
}
-QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
+QFont QCoreTextFontEngine::createExplicitFont() const
+{
+ QString familyName = QCFString::toQString(CTFontCopyFamilyName(ctfont));
+ return createExplicitFontWithName(familyName);
+}
+
+QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa)
{
const glyph_metrics_t br = boundingBox(glyph);
QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32);
@@ -690,11 +692,10 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
CGContextSetTextDrawingMode(ctx, kCGTextFill);
- ATSFontRef atsfont = CTFontGetPlatformFont(ctfont, 0);
- QCFType<CGFontRef> cgFont = CGFontCreateWithPlatformFont(&atsfont);
CGContextSetFont(ctx, cgFont);
- qreal pos_x = -br.x.toReal()+1, pos_y = im.height()+br.y.toReal();
+ qreal pos_x = -br.x.toReal() + subPixelPosition.toReal();
+ qreal pos_y = im.height()+br.y.toReal();
CGContextSetTextPosition(ctx, pos_x, pos_y);
CGSize advance;
@@ -715,7 +716,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
{
- QImage im = imageForGlyph(glyph, 0, false);
+ QImage im = imageForGlyph(glyph, QFixed(), 0, false);
QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
QVector<QRgb> colors(256);
@@ -736,12 +737,12 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
return indexed;
}
-QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &x)
+QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, const QTransform &x)
{
if (x.type() >= QTransform::TxScale)
- return QFontEngine::alphaRGBMapForGlyph(glyph, margin, x);
+ return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, margin, x);
- QImage im = imageForGlyph(glyph, margin, true);
+ QImage im = imageForGlyph(glyph, subPixelPosition, margin, true);
qmacfontengine_gamma_correct(&im);
return im;
}
@@ -1420,6 +1421,7 @@ static inline unsigned int getChar(const QChar *str, int &i, const int len)
return uc;
}
+// Not used directly for shaping, only used to calculate m_averageCharWidth
bool QFontEngineMac::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
{
if (!cmap) {
@@ -1592,6 +1594,27 @@ static void addGlyphsToPathHelper(ATSUStyle style, glyph_t *glyphs, QFixedPoint
DisposeATSCubicClosePathUPP(closePath);
}
+QFont QFontEngineMac::createExplicitFont() const
+{
+ FMFont fmFont = FMGetFontFromATSFontRef(fontID);
+
+ FMFontFamily fmFamily;
+ FMFontStyle fmStyle;
+ QString familyName;
+ if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) {
+ ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily);
+ QCFString cfFamilyName;;
+ ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName);
+ familyName = cfFamilyName;
+ } else {
+ QCFString cfFontName;
+ ATSFontGetName(fontID, kATSOptionFlagsDefault, &cfFontName);
+ familyName = cfFontName;
+ }
+
+ return createExplicitFontWithName(familyName);
+}
+
void QFontEngineMac::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path,
QTextItem::RenderFlags)
{
@@ -1678,7 +1701,7 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
return indexed;
}
-QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t)
+QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
{
QImage im = imageForGlyph(glyph, margin, true);
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 3b91cd829a..b3a6c594f7 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -155,6 +155,7 @@ public:
SynthesizedStretch = 0x4
};
virtual int synthesized() const { return 0; }
+ virtual bool supportsSubPixelPositions() const { return false; }
virtual QFixed emSquareSize() const { return ascent(); }
@@ -173,6 +174,10 @@ public:
#endif
virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags);
+
+ /* Creates a QFont object to represent this particular QFontEngine */
+ virtual QFont createExplicitFont() const;
+
void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags,
QVarLengthArray<glyph_t> &glyphs_out, QVarLengthArray<QFixedPoint> &positions);
@@ -184,7 +189,7 @@ public:
*/
virtual QImage alphaMapForGlyph(glyph_t);
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual void removeGlyphFromCache(glyph_t);
@@ -252,13 +257,14 @@ public:
int glyphFormat;
protected:
+ QFont createExplicitFontWithName(const QString &familyName) const;
static const QVector<QRgb> &grayPalette();
QFixed lastRightBearing(const QGlyphLayout &glyphs, bool round = false);
private:
struct GlyphCacheEntry {
void *context;
- QFontEngineGlyphCache *cache;
+ QExplicitlySharedDataPointer<QFontEngineGlyphCache> cache;
bool operator==(const GlyphCacheEntry &other) { return context == other.context && cache == other.cache; }
};
@@ -443,6 +449,7 @@ public:
virtual bool canRender(const QChar *string, int len);
virtual int synthesized() const { return synthesisFlags; }
+ virtual bool supportsSubPixelPositions() const { return true; }
virtual Type type() const { return QFontEngine::Mac; }
@@ -452,13 +459,13 @@ public:
virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
virtual QImage alphaMapForGlyph(glyph_t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual qreal minRightBearing() const;
virtual qreal minLeftBearing() const;
-
+ virtual QFont createExplicitFont() const;
private:
- QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
+ QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful);
CTFontRef ctfont;
CGFontRef cgFont;
QCoreTextFontEngineMulti *parentEngine;
@@ -470,8 +477,7 @@ private:
class QCoreTextFontEngineMulti : public QFontEngineMulti
{
public:
- QCoreTextFontEngineMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef,
- const QFontDef &fontDef, bool kerning);
+ QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning);
~QCoreTextFontEngineMulti();
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
@@ -521,6 +527,8 @@ public:
virtual qreal maxCharWidth() const;
virtual QFixed averageCharWidth() const;
+ virtual QFont createExplicitFont() const;
+
virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,
QPainterPath *path, QTextItem::RenderFlags);
@@ -539,7 +547,7 @@ public:
virtual Properties properties() const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
virtual QImage alphaMapForGlyph(glyph_t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
private:
QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index 5980f201d3..e9dcfa077c 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -122,7 +122,8 @@ QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const
Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag));
TInt error = KErrNone;
TInt tableByteLength = 0;
- TAny *table = q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength));
+ TAny *table = m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength);
+ Q_CHECK_PTR(table);
QByteArray result(static_cast<const char*>(table), tableByteLength);
m_trueTypeExtension->ReleaseTrueTypeTable(table);
return result;
@@ -136,8 +137,8 @@ bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *len
bool result = true;
TInt error = KErrNone;
TInt tableByteLength;
- TAny *table =
- q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength));
+ TAny *table = m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength);
+ Q_CHECK_PTR(table);
if (error != KErrNone) {
return false;
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index ef1b504871..3006776040 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -1254,7 +1254,7 @@ QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
-QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t)
+QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
{
HFONT font = hfont;
diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h
index 68b53b5235..d86f42e504 100644
--- a/src/gui/text/qfontengine_win_p.h
+++ b/src/gui/text/qfontengine_win_p.h
@@ -104,7 +104,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
- virtual QImage alphaRGBMapForGlyph(glyph_t t, int margin, const QTransform &xform);
+ virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
#ifndef Q_CC_MINGW
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
index b7e4be2c9a..aee21f6e46 100644
--- a/src/gui/text/qfontengine_x11.cpp
+++ b/src/gui/text/qfontengine_x11.cpp
@@ -992,7 +992,7 @@ QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int s
face_id.filename = file_name;
face_id.index = face_index;
- canUploadGlyphsToServer = qApp->thread() == QThread::currentThread();
+ canUploadGlyphsToServer = QApplication::testAttribute(Qt::AA_X11InitThreads) || (qApp->thread() == QThread::currentThread());
subpixelType = Subpixel_None;
if (antialias) {
diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h
index 7b82b461cf..eba16f7602 100644
--- a/src/gui/text/qfontengineglyphcache_p.h
+++ b/src/gui/text/qfontengineglyphcache_p.h
@@ -72,7 +72,7 @@
QT_BEGIN_NAMESPACE
-class QFontEngineGlyphCache
+class QFontEngineGlyphCache: public QSharedData
{
public:
enum Type {
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index d02e841c8c..f2591ce517 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -443,6 +443,21 @@ bool QFontMetrics::inFont(QChar ch) const
}
/*!
+ Returns true if the character encoded in UCS-4/UTF-32 is a valid
+ character in the font; otherwise returns false.
+*/
+bool QFontMetrics::inFontUcs4(uint ucs4) const
+{
+ const int script = QUnicodeTables::script(ucs4);
+ QFontEngine *engine = d->engineForScript(script);
+ Q_ASSERT(engine != 0);
+ if (engine->type() == QFontEngine::Box)
+ return false;
+ QString utf16 = QString::fromUcs4(&ucs4, 1);
+ return engine->canRender(utf16.data(), utf16.length());
+}
+
+/*!
Returns the left bearing of character \a ch in the font.
The left bearing is the right-ward distance of the left-most pixel
@@ -1315,6 +1330,21 @@ bool QFontMetricsF::inFont(QChar ch) const
}
/*!
+ Returns true if the character encoded in UCS-4/UTF-32 is a valid
+ character in the font; otherwise returns false.
+*/
+bool QFontMetricsF::inFontUcs4(uint ucs4) const
+{
+ const int script = QUnicodeTables::script(ucs4);
+ QFontEngine *engine = d->engineForScript(script);
+ Q_ASSERT(engine != 0);
+ if (engine->type() == QFontEngine::Box)
+ return false;
+ QString utf16 = QString::fromUcs4(&ucs4, 1);
+ return engine->canRender(utf16.data(), utf16.length());
+}
+
+/*!
Returns the left bearing of character \a ch in the font.
The left bearing is the right-ward distance of the left-most pixel
@@ -1779,7 +1809,7 @@ qreal QFontMetricsF::lineWidth() const
Use the boundingRect() function in combination with
QString::left() instead.
-
+
\oldcode
QRect rect = boundingRect(text, len);
\newcode
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index 2518b5406a..5a79429358 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -71,6 +71,10 @@ public:
~QFontMetrics();
QFontMetrics &operator=(const QFontMetrics &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QFontMetrics &operator=(QFontMetrics &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
int ascent() const;
int descent() const;
@@ -85,6 +89,7 @@ public:
int averageCharWidth() const;
bool inFont(QChar) const;
+ bool inFontUcs4(uint ucs4) const;
int leftBearing(QChar) const;
int rightBearing(QChar) const;
@@ -148,7 +153,10 @@ public:
QFontMetricsF &operator=(const QFontMetricsF &);
QFontMetricsF &operator=(const QFontMetrics &);
-
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QFontMetricsF &operator=(QFontMetricsF &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
qreal ascent() const;
qreal descent() const;
qreal height() const;
@@ -162,6 +170,7 @@ public:
qreal averageCharWidth() const;
bool inFont(QChar) const;
+ bool inFontUcs4(uint ucs4) const;
qreal leftBearing(QChar) const;
qreal rightBearing(QChar) const;
diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp
new file mode 100644
index 0000000000..2447752581
--- /dev/null
+++ b/src/gui/text/qglyphs.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 "qglyphs.h"
+#include "qglyphs_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGlyphs
+ \brief the QGlyphs class provides direct access to the internal glyphs in a font
+ \since 4.8
+
+ \ingroup text
+ \mainclass
+
+ When Qt displays a string of text encoded in Unicode, it will first convert the Unicode points
+ into a list of glyph indexes and a list of positions based on one or more fonts. The Unicode
+ representation of the text and the QFont object will in this case serve as a convenient
+ abstraction that hides the details of what actually takes place when displaying the text
+ on-screen. For instance, by the time the text actually reaches the screen, it may be represented
+ by a set of fonts in addition to the one specified by the user, e.g. in case the originally
+ selected font did not support all the writing systems contained in the text.
+
+ Under certain circumstances, it can be useful as an application developer to have more low-level
+ control over which glyphs in a specific font are drawn to the screen. This could for instance
+ be the case in applications that use an external font engine and text shaper together with Qt.
+ QGlyphs provides an interface to the raw data needed to get text on the screen. It
+ contains a list of glyph indexes, a position for each glyph and a font.
+
+ It is the user's responsibility to ensure that the selected font actually contains the
+ provided glyph indexes.
+
+ QTextLayout::glyphs() can be used to convert unicode encoded text into a list of QGlyphs
+ objects, and QPainter::drawGlyphs() can be used to draw the glyphs.
+*/
+
+
+/*!
+ Constructs an empty QGlyphs object.
+*/
+QGlyphs::QGlyphs() : d(new QGlyphsPrivate)
+{
+}
+
+/*!
+ Constructs a QGlyphs object which is a copy of \a other.
+*/
+QGlyphs::QGlyphs(const QGlyphs &other)
+{
+ d = other.d;
+}
+
+/*!
+ Destroys the QGlyphs.
+*/
+QGlyphs::~QGlyphs()
+{
+ // Required for QExplicitlySharedDataPointer
+}
+
+/*!
+ \internal
+*/
+void QGlyphs::detach()
+{
+ if (d->ref != 1)
+ d.detach();
+}
+
+/*!
+ Assigns \a other to this QGlyphs object.
+*/
+QGlyphs &QGlyphs::operator=(const QGlyphs &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Compares \a other to this QGlyphs object. Returns true if the list of glyph indexes,
+ the list of positions and the font are all equal, otherwise returns false.
+*/
+bool QGlyphs::operator==(const QGlyphs &other) const
+{
+ return ((d == other.d)
+ || (d->glyphIndexes == other.d->glyphIndexes
+ && d->glyphPositions == other.d->glyphPositions
+ && d->font == other.d->font));
+}
+
+/*!
+ Compares \a other to this QGlyphs object. Returns true if any of the list of glyph
+ indexes, the list of positions or the font are different, otherwise returns false.
+*/
+bool QGlyphs::operator!=(const QGlyphs &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ \internal
+
+ Adds together the lists of glyph indexes and positions in \a other and this QGlyphs
+ object and returns the result. The font in the returned QGlyphs will be the same as in
+ this QGlyphs object.
+*/
+QGlyphs QGlyphs::operator+(const QGlyphs &other) const
+{
+ QGlyphs ret(*this);
+ ret += other;
+ return ret;
+}
+
+/*!
+ \internal
+
+ Appends the glyph indexes and positions in \a other to this QGlyphs object and returns
+ a reference to the current object.
+*/
+QGlyphs &QGlyphs::operator+=(const QGlyphs &other)
+{
+ detach();
+
+ d->glyphIndexes += other.d->glyphIndexes;
+ d->glyphPositions += other.d->glyphPositions;
+
+ return *this;
+}
+
+/*!
+ Returns the font selected for this QGlyphs object.
+
+ \sa setFont()
+*/
+QFont QGlyphs::font() const
+{
+ return d->font;
+}
+
+/*!
+ Sets the font in which to look up the glyph indexes to \a font. This must be an explicitly
+ resolvable font which defines glyphs for the specified glyph indexes.
+
+ \sa font(), setGlyphIndexes()
+*/
+void QGlyphs::setFont(const QFont &font)
+{
+ detach();
+ d->font = font;
+}
+
+/*!
+ Returns the glyph indexes for this QGlyphs object.
+
+ \sa setGlyphIndexes(), setPositions()
+*/
+QVector<quint32> QGlyphs::glyphIndexes() const
+{
+ return d->glyphIndexes;
+}
+
+/*!
+ Set the glyph indexes for this QGlyphs object to \a glyphIndexes. The glyph indexes must
+ be valid for the selected font.
+*/
+void QGlyphs::setGlyphIndexes(const QVector<quint32> &glyphIndexes)
+{
+ detach();
+ d->glyphIndexes = glyphIndexes;
+}
+
+/*!
+ Returns the position of the edge of the baseline for each glyph in this set of glyph indexes.
+*/
+QVector<QPointF> QGlyphs::positions() const
+{
+ return d->glyphPositions;
+}
+
+/*!
+ Sets the positions of the edge of the baseline for each glyph in this set of glyph indexes to
+ \a positions.
+*/
+void QGlyphs::setPositions(const QVector<QPointF> &positions)
+{
+ detach();
+ d->glyphPositions = positions;
+}
+
+/*!
+ Clears all data in the QGlyphs object.
+*/
+void QGlyphs::clear()
+{
+ detach();
+ d->glyphPositions = QVector<QPointF>();
+ d->glyphIndexes = QVector<quint32>();
+ d->font = QFont();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/text/qglyphs.h b/src/gui/text/qglyphs.h
new file mode 100644
index 0000000000..282ecb47c5
--- /dev/null
+++ b/src/gui/text/qglyphs.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 QGLYPHS_H
+#define QGLYPHS_H
+
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qpoint.h>
+#include <QtGui/qfont.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGlyphsPrivate;
+class Q_GUI_EXPORT QGlyphs
+{
+public:
+ QGlyphs();
+ QGlyphs(const QGlyphs &other);
+ ~QGlyphs();
+
+ QFont font() const;
+ void setFont(const QFont &font);
+
+ QVector<quint32> glyphIndexes() const;
+ void setGlyphIndexes(const QVector<quint32> &glyphIndexes);
+
+ QVector<QPointF> positions() const;
+ void setPositions(const QVector<QPointF> &positions);
+
+ void clear();
+
+ QGlyphs &operator=(const QGlyphs &other);
+ bool operator==(const QGlyphs &other) const;
+ bool operator!=(const QGlyphs &other) const;
+
+private:
+ friend class QGlyphsPrivate;
+ friend class QTextLine;
+
+ QGlyphs operator+(const QGlyphs &other) const;
+ QGlyphs &operator+=(const QGlyphs &other);
+
+ void detach();
+ QExplicitlySharedDataPointer<QGlyphsPrivate> d;
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QGLYPHS_H
diff --git a/src/gui/text/qglyphs_p.h b/src/gui/text/qglyphs_p.h
new file mode 100644
index 0000000000..c39f5d0e56
--- /dev/null
+++ b/src/gui/text/qglyphs_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 QGLYPHS_P_H
+#define QGLYPHS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qfont.h>
+#include "qglyphs.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QGlyphsPrivate: public QSharedData
+{
+public:
+ QGlyphsPrivate()
+ {
+ }
+
+ QGlyphsPrivate(const QGlyphsPrivate &other)
+ : QSharedData(other), glyphIndexes(other.glyphIndexes), glyphPositions(other.glyphPositions), font(other.font)
+ {
+ }
+
+ QVector<quint32> glyphIndexes;
+ QVector<QPointF> glyphPositions;
+ QFont font;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGLYPHS_P_H
diff --git a/src/gui/text/qpfutil.cpp b/src/gui/text/qpfutil.cpp
index 376f49cd91..7f8c58e5f0 100644
--- a/src/gui/text/qpfutil.cpp
+++ b/src/gui/text/qpfutil.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-static QFontEngineQPF::TagType tagTypes[QFontEngineQPF::NumTags] = {
+static const QFontEngineQPF::TagType tagTypes[QFontEngineQPF::NumTags] = {
QFontEngineQPF::StringType, // FontName
QFontEngineQPF::StringType, // FileName
QFontEngineQPF::UInt32Type, // FileIndex
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 5fe0c0cee0..441a8c8b4d 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -2900,7 +2900,7 @@ QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget
if (widget)
style = widget->style();
style->styleHint(QStyle::SH_TextControl_FocusIndicatorTextCharFormat, &opt, widget, &ret);
- selection.format = qVariantValue<QTextFormat>(ret.variant).toCharFormat();
+ selection.format = qvariant_cast<QTextFormat>(ret.variant).toCharFormat();
} else {
QPalette::ColorGroup cg = d->hasFocus ? QPalette::Active : QPalette::Inactive;
selection.format.setBackground(ctx.palette.brush(cg, QPalette::Highlight));
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index c35069f112..3aa6795755 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1983,6 +1983,8 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
if (fi.exists()) {
resourceUrl =
QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(name);
+ } else if (currentURL.isEmpty()) {
+ resourceUrl.setScheme(QLatin1String("file"));
}
}
@@ -2600,14 +2602,40 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
default: html += QLatin1String("<ul"); // ### should not happen
}
- html += QLatin1String(" style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px;");
+ QString styleString = QString::fromLatin1("margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px;");
if (format.hasProperty(QTextFormat::ListIndent)) {
- html += QLatin1String(" -qt-list-indent: ");
- html += QString::number(format.indent());
- html += QLatin1Char(';');
+ styleString += QLatin1String(" -qt-list-indent: ");
+ styleString += QString::number(format.indent());
+ styleString += QLatin1Char(';');
+ }
+
+ if (format.hasProperty(QTextFormat::ListNumberPrefix)) {
+ QString numberPrefix = format.numberPrefix();
+ numberPrefix.replace('"', "\\22");
+ numberPrefix.replace('\'', "\\27"); // FIXME: There's a problem in the CSS parser the prevents this from being correctly restored
+ styleString += QLatin1String(" -qt-list-number-prefix: ");
+ styleString += QLatin1Char('\'');
+ styleString += numberPrefix;
+ styleString += QLatin1Char('\'');
+ styleString += QLatin1Char(';');
}
+ if (format.hasProperty(QTextFormat::ListNumberSuffix)) {
+ if (format.numberSuffix() != QLatin1String(".")) { // this is our default
+ QString numberSuffix = format.numberSuffix();
+ numberSuffix.replace('"', "\\22");
+ numberSuffix.replace('\'', "\\27"); // see above
+ styleString += QLatin1String(" -qt-list-number-suffix: ");
+ styleString += QLatin1Char('\'');
+ styleString += numberSuffix;
+ styleString += QLatin1Char('\'');
+ styleString += QLatin1Char(';');
+ }
+ }
+
+ html += QLatin1String(" style=\"");
+ html += styleString;
html += QLatin1String("\">");
}
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index 7c5f9731ce..d2e2c9f27f 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -683,6 +683,10 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processSpecialNodes()
QTextListFormat listFmt;
listFmt.setStyle(style);
+ if (!currentNode->textListNumberPrefix.isNull())
+ listFmt.setNumberPrefix(currentNode->textListNumberPrefix);
+ if (!currentNode->textListNumberSuffix.isNull())
+ listFmt.setNumberSuffix(currentNode->textListNumberSuffix);
++indent;
if (currentNode->hasCssListIndent)
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 05de8f5ad8..34d9fa6b9a 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1389,6 +1389,7 @@ void QTextEngine::invalidate()
maxWidth = 0;
if (specialData)
specialData->resolvedFormatIndices.clear();
+ feCache.reset();
}
void QTextEngine::clearLineData()
@@ -1780,6 +1781,13 @@ QFont QTextEngine::font(const QScriptItem &si) const
return font;
}
+QTextEngine::FontEngineCache::FontEngineCache()
+{
+ reset();
+}
+
+//we cache the previous results of this function, as calling it numerous times with the same effective
+//input is common (and hard to cache at a higher level)
QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent, QFixed *leading) const
{
QFontEngine *engine = 0;
@@ -1788,28 +1796,47 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
QFont font = fnt;
if (hasFormats()) {
- QTextCharFormat f = format(&si);
- font = f.font();
-
- if (block.docHandle() && block.docHandle()->layout()) {
- // Make sure we get the right dpi on printers
- QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
- if (pdev)
- font = QFont(font, pdev);
+ if (feCache.prevFontEngine && feCache.prevPosition == si.position && feCache.prevLength == length(&si) && feCache.prevScript == script) {
+ engine = feCache.prevFontEngine;
+ scaledEngine = feCache.prevScaledFontEngine;
} else {
- font = font.resolve(fnt);
- }
- engine = font.d->engineForScript(script);
- QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();
- if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
- if (font.pointSize() != -1)
- font.setPointSize((font.pointSize() * 2) / 3);
- else
- font.setPixelSize((font.pixelSize() * 2) / 3);
- scaledEngine = font.d->engineForScript(script);
+ QTextCharFormat f = format(&si);
+ font = f.font();
+
+ if (block.docHandle() && block.docHandle()->layout()) {
+ // Make sure we get the right dpi on printers
+ QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
+ if (pdev)
+ font = QFont(font, pdev);
+ } else {
+ font = font.resolve(fnt);
+ }
+ engine = font.d->engineForScript(script);
+ QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();
+ if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
+ if (font.pointSize() != -1)
+ font.setPointSize((font.pointSize() * 2) / 3);
+ else
+ font.setPixelSize((font.pixelSize() * 2) / 3);
+ scaledEngine = font.d->engineForScript(script);
+ }
+ feCache.prevFontEngine = engine;
+ feCache.prevScaledFontEngine = scaledEngine;
+ feCache.prevScript = script;
+ feCache.prevPosition = si.position;
+ feCache.prevLength = length(&si);
}
} else {
- engine = font.d->engineForScript(script);
+ if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1)
+ engine = feCache.prevFontEngine;
+ else {
+ engine = font.d->engineForScript(script);
+ feCache.prevFontEngine = engine;
+ feCache.prevScript = script;
+ feCache.prevPosition = -1;
+ feCache.prevLength = -1;
+ feCache.prevScaledFontEngine = 0;
+ }
}
if (si.analysis.flags == QScriptAnalysis::SmallCaps) {
@@ -2349,30 +2376,29 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
if (flags & Qt::TextShowMnemonic) {
itemize();
+ HB_CharAttributes *attributes = const_cast<HB_CharAttributes *>(this->attributes());
+ if (!attributes)
+ return QString();
for (int i = 0; i < layoutData->items.size(); ++i) {
QScriptItem &si = layoutData->items[i];
if (!si.num_glyphs)
shape(i);
- HB_CharAttributes *attributes = const_cast<HB_CharAttributes *>(this->attributes());
- if (!attributes)
- return QString();
-
unsigned short *logClusters = this->logClusters(&si);
QGlyphLayout glyphs = shapedGlyphs(&si);
const int end = si.position + length(&si);
- for (int i = si.position; i < end - 1; ++i)
+ for (int i = si.position; i < end - 1; ++i) {
if (layoutData->string.at(i) == QLatin1Char('&')) {
const int gp = logClusters[i - si.position];
glyphs.attributes[gp].dontPrint = true;
attributes[i + 1].charStop = false;
attributes[i + 1].whiteSpace = false;
attributes[i + 1].lineBreakType = HB_NoBreak;
- if (i < end - 1
- && layoutData->string.at(i + 1) == QLatin1Char('&'))
+ if (layoutData->string.at(i + 1) == QLatin1Char('&'))
++i;
}
+ }
}
}
@@ -2434,7 +2460,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
if (mode == Qt::ElideRight) {
QFixed currentWidth;
- int pos = 0;
+ int pos;
int nextBreak = 0;
do {
@@ -2454,7 +2480,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
return layoutData->string.left(pos) + ellipsisText;
} else if (mode == Qt::ElideLeft) {
QFixed currentWidth;
- int pos = layoutData->string.length();
+ int pos;
int nextBreak = layoutData->string.length();
do {
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 4cbe81fc42..b5faf2023d 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -128,7 +128,7 @@ struct Q_AUTOTEST_EXPORT QScriptAnalysis
TabOrObject = Tab,
Object = 7
};
- unsigned short script : 8;
+ unsigned short script : 7;
unsigned short bidiLevel : 6; // Unicode Bidi algorithm embedding level (0-61)
unsigned short flags : 3;
inline bool operator == (const QScriptAnalysis &other) const {
@@ -385,7 +385,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
QFixed textWidth;
QFixed textAdvance;
int from;
- signed int length : 29;
+ signed int length : 28;
mutable uint justified : 1;
mutable uint gridfitted : 1;
uint hasTrailingSpaces : 1;
@@ -435,7 +435,7 @@ public:
uint hasBidi : 1;
uint layoutState : 2;
uint memory_on_stack : 1;
- bool haveCharAttributes;
+ uint haveCharAttributes : 1;
QString string;
bool reallocate(int totalGlyphs);
};
@@ -556,6 +556,23 @@ public:
mutable QScriptLineArray lines;
+ struct FontEngineCache {
+ FontEngineCache();
+ mutable QFontEngine *prevFontEngine;
+ mutable QFontEngine *prevScaledFontEngine;
+ mutable int prevScript;
+ mutable int prevPosition;
+ mutable int prevLength;
+ inline void reset() {
+ prevFontEngine = 0;
+ prevScaledFontEngine = 0;
+ prevScript = -1;
+ prevPosition = -1;
+ prevLength = -1;
+ }
+ };
+ mutable FontEngineCache feCache;
+
QString text;
QFont fnt;
QTextBlock block;
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 46db25397b..ffa0ebc535 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -925,7 +925,7 @@ qreal QTextFormat::doubleProperty(int propertyId) const
const QVariant prop = d->property(propertyId);
if (prop.userType() != QVariant::Double && prop.userType() != QMetaType::Float)
return 0.;
- return qVariantValue<qreal>(prop);
+ return qvariant_cast<qreal>(prop);
}
/*!
@@ -1895,7 +1895,7 @@ void QTextBlockFormat::setTabPositions(const QList<QTextOption::Tab> &tabs)
QList<QTextOption::Tab>::ConstIterator iter = tabs.constBegin();
while (iter != tabs.constEnd()) {
QVariant v;
- qVariantSetValue<QTextOption::Tab>(v, *iter);
+ v.setValue<QTextOption::Tab>(*iter);
list.append(v);
++iter;
}
@@ -1917,7 +1917,7 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
QList<QVariant> variantsList = qvariant_cast<QList<QVariant> >(variant);
QList<QVariant>::Iterator iter = variantsList.begin();
while(iter != variantsList.end()) {
- answer.append( qVariantValue<QTextOption::Tab>(*iter));
+ answer.append( qvariant_cast<QTextOption::Tab>(*iter));
++iter;
}
return answer;
@@ -2227,6 +2227,44 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt)
\sa setIndent()
*/
+/*!
+ \fn void QTextListFormat::setNumberPrefix(const QString &numberPrefix)
+ \since 4.8
+
+ Sets the list format's number prefix. This can be used with all
+ sorted list types. It does not have any effect on unsorted list types.
+
+ \sa numberPrefix()
+*/
+
+/*!
+ \fn int QTextListFormat::numberPrefix() const
+ \since 4.8
+
+ Returns the list format's number prefix.
+
+ \sa setNumberPrefix()
+*/
+
+/*!
+ \fn void QTextListFormat::setNumberSuffix(const QString &numberSuffix)
+ \since 4.8
+
+ Sets the list format's number suffix. This can be used with all
+ sorted list types. It does not have any effect on unsorted list types.
+ The default suffix is ".".
+
+ \sa numberSuffix()
+*/
+
+/*!
+ \fn int QTextListFormat::numberSuffix() const
+ \since 4.8
+
+ Returns the list format's number suffix.
+
+ \sa setNumberSuffix()
+*/
/*!
\class QTextFrameFormat
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index ecf48a2e5f..bb6e71d8b6 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -202,6 +202,8 @@ public:
// list properties
ListStyle = 0x3000,
ListIndent = 0x3001,
+ ListNumberPrefix = 0x3002,
+ ListNumberSuffix = 0x3003,
// table and frame properties
FrameBorder = 0x4000,
@@ -617,6 +619,14 @@ public:
inline int indent() const
{ return intProperty(ListIndent); }
+ inline void setNumberPrefix(const QString &numberPrefix);
+ inline QString numberPrefix() const
+ { return stringProperty(ListNumberPrefix); }
+
+ inline void setNumberSuffix(const QString &numberSuffix);
+ inline QString numberSuffix() const
+ { return stringProperty(ListNumberSuffix); }
+
protected:
explicit QTextListFormat(const QTextFormat &fmt);
friend class QTextFormat;
@@ -628,6 +638,12 @@ inline void QTextListFormat::setStyle(Style astyle)
inline void QTextListFormat::setIndent(int aindent)
{ setProperty(ListIndent, aindent); }
+inline void QTextListFormat::setNumberPrefix(const QString &np)
+{ setProperty(ListNumberPrefix, np); }
+
+inline void QTextListFormat::setNumberSuffix(const QString &ns)
+{ setProperty(ListNumberSuffix, ns); }
+
class Q_GUI_EXPORT QTextImageFormat : public QTextCharFormat
{
public:
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index e19037903e..27f647c240 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1324,6 +1324,12 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
case QCss::ListStyle:
setListStyle(decl.d->values);
break;
+ case QCss::QtListNumberPrefix:
+ textListNumberPrefix = decl.d->values.first().variant.toString();
+ break;
+ case QCss::QtListNumberSuffix:
+ textListNumberSuffix = decl.d->values.first().variant.toString();
+ break;
default: break;
}
}
diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h
index 94cfa74b9c..20188ab01c 100644
--- a/src/gui/text/qtexthtmlparser_p.h
+++ b/src/gui/text/qtexthtmlparser_p.h
@@ -180,6 +180,8 @@ struct QTextHtmlParserNode {
uint displayMode : 3; // QTextHtmlElement::DisplayMode
uint hasHref : 1;
QTextListFormat::Style listStyle;
+ QString textListNumberPrefix;
+ QString textListNumberSuffix;
QString imageName;
qreal imageWidth;
qreal imageHeight;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index f432b7e629..3f83aee7c2 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -52,6 +52,8 @@
#include "qtextformat_p.h"
#include "qstyleoption.h"
#include "qpainterpath.h"
+#include "qglyphs.h"
+#include "qglyphs_p.h"
#include <limits.h>
#include <qdebug.h>
@@ -165,7 +167,7 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line)
/*!
Returns the inline object's rectangle.
- \sa ascent() descent() width()
+ \sa ascent(), descent(), width()
*/
QRectF QTextInlineObject::rect() const
{
@@ -176,7 +178,7 @@ QRectF QTextInlineObject::rect() const
/*!
Returns the inline object's width.
- \sa ascent() descent() rect()
+ \sa ascent(), descent(), rect()
*/
qreal QTextInlineObject::width() const
{
@@ -186,7 +188,7 @@ qreal QTextInlineObject::width() const
/*!
Returns the inline object's ascent.
- \sa descent() width() rect()
+ \sa descent(), width(), rect()
*/
qreal QTextInlineObject::ascent() const
{
@@ -196,7 +198,7 @@ qreal QTextInlineObject::ascent() const
/*!
Returns the inline object's descent.
- \sa ascent() width() rect()
+ \sa ascent(), width(), rect()
*/
qreal QTextInlineObject::descent() const
{
@@ -207,18 +209,17 @@ qreal QTextInlineObject::descent() const
Returns the inline object's total height. This is equal to
ascent() + descent() + 1.
- \sa ascent() descent() width() rect()
+ \sa ascent(), descent(), width(), rect()
*/
qreal QTextInlineObject::height() const
{
return eng->layoutData->items[itm].height().toReal();
}
-
/*!
Sets the inline object's width to \a w.
- \sa width() ascent() descent() rect()
+ \sa width(), ascent(), descent(), rect()
*/
void QTextInlineObject::setWidth(qreal w)
{
@@ -228,7 +229,7 @@ void QTextInlineObject::setWidth(qreal w)
/*!
Sets the inline object's ascent to \a a.
- \sa ascent() setDescent() width() rect()
+ \sa ascent(), setDescent(), width(), rect()
*/
void QTextInlineObject::setAscent(qreal a)
{
@@ -238,7 +239,7 @@ void QTextInlineObject::setAscent(qreal a)
/*!
Sets the inline object's decent to \a d.
- \sa descent() setAscent() width() rect()
+ \sa descent(), setAscent(), width(), rect()
*/
void QTextInlineObject::setDescent(qreal d)
{
@@ -246,7 +247,7 @@ void QTextInlineObject::setDescent(qreal d)
}
/*!
- The position of the inline object within the text layout.
+ The position of the inline object within the text layout.
*/
int QTextInlineObject::textPosition() const
{
@@ -254,8 +255,8 @@ int QTextInlineObject::textPosition() const
}
/*!
- Returns an integer describing the format of the inline object
- within the text layout.
+ Returns an integer describing the format of the inline object
+ within the text layout.
*/
int QTextInlineObject::formatIndex() const
{
@@ -263,7 +264,7 @@ int QTextInlineObject::formatIndex() const
}
/*!
- Returns format of the inline object within the text layout.
+ Returns format of the inline object within the text layout.
*/
QTextFormat QTextInlineObject::format() const
{
@@ -273,7 +274,7 @@ QTextFormat QTextInlineObject::format() const
}
/*!
- Returns if the object should be laid out right-to-left or left-to-right.
+ Returns if the object should be laid out right-to-left or left-to-right.
*/
Qt::LayoutDirection QTextInlineObject::textDirection() const
{
@@ -325,7 +326,6 @@ Qt::LayoutDirection QTextInlineObject::textDirection() const
boundingRect(), and a minimumWidth() and a maximumWidth().
\sa QStaticText
-
*/
/*!
@@ -398,16 +398,19 @@ QTextLayout::~QTextLayout()
Sets the layout's font to the given \a font. The layout is
invalidated and must be laid out again.
- \sa text()
+ \sa font()
*/
void QTextLayout::setFont(const QFont &font)
{
d->fnt = font;
+ d->feCache.reset();
}
/*!
Returns the current font that is used for the layout, or a default
font if none is set.
+
+ \sa setFont()
*/
QFont QTextLayout::font() const
{
@@ -441,10 +444,10 @@ QString QTextLayout::text() const
}
/*!
- Sets the text option structure that controls the layout process to the
- given \a option.
+ Sets the text option structure that controls the layout process to the
+ given \a option.
- \sa textOption() QTextOption
+ \sa textOption()
*/
void QTextLayout::setTextOption(const QTextOption &option)
{
@@ -452,9 +455,9 @@ void QTextLayout::setTextOption(const QTextOption &option)
}
/*!
- Returns the current text option used to control the layout process.
+ Returns the current text option used to control the layout process.
- \sa setTextOption() QTextOption
+ \sa setTextOption()
*/
QTextOption QTextLayout::textOption() const
{
@@ -464,6 +467,8 @@ QTextOption QTextLayout::textOption() const
/*!
Sets the \a position and \a text of the area in the layout that is
processed before editing occurs.
+
+ \sa preeditAreaPosition(), preeditAreaText()
*/
void QTextLayout::setPreeditArea(int position, const QString &text)
{
@@ -492,6 +497,8 @@ void QTextLayout::setPreeditArea(int position, const QString &text)
/*!
Returns the position of the area in the text layout that will be
processed before editing occurs.
+
+ \sa preeditAreaText()
*/
int QTextLayout::preeditAreaPosition() const
{
@@ -500,6 +507,8 @@ int QTextLayout::preeditAreaPosition() const
/*!
Returns the text that is inserted in the layout before editing occurs.
+
+ \sa preeditAreaPosition()
*/
QString QTextLayout::preeditAreaText() const
{
@@ -508,8 +517,7 @@ QString QTextLayout::preeditAreaText() const
/*!
- Sets the additional formats supported by the text layout to \a
- formatList.
+ Sets the additional formats supported by the text layout to \a formatList.
\sa additionalFormats(), clearAdditionalFormats()
*/
@@ -535,6 +543,7 @@ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList)
}
if (d->block.docHandle())
d->block.docHandle()->documentChange(d->block.position(), d->block.length());
+ d->feCache.reset();
}
/*!
@@ -599,6 +608,8 @@ bool QTextLayout::cacheEnabled() const
/*!
Begins the layout process.
+
+ \sa endLayout()
*/
void QTextLayout::beginLayout()
{
@@ -616,6 +627,8 @@ void QTextLayout::beginLayout()
/*!
Ends the layout process.
+
+ \sa beginLayout()
*/
void QTextLayout::endLayout()
{
@@ -634,35 +647,33 @@ void QTextLayout::endLayout()
d->freeMemory();
}
-/*! \since 4.4
+/*!
+ \since 4.4
-Clears the line information in the layout. After having called
-this function, lineCount() returns 0.
- */
+ Clears the line information in the layout. After having called
+ this function, lineCount() returns 0.
+*/
void QTextLayout::clearLayout()
{
d->clearLineData();
}
-
/*!
Returns the next valid cursor position after \a oldPos that
respects the given cursor \a mode.
+ Returns value of \a oldPos, if \a oldPos is not a valid cursor position.
- \sa isValidCursorPosition() previousCursorPosition()
+ \sa isValidCursorPosition(), previousCursorPosition()
*/
int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
{
-// qDebug("looking for next cursor pos for %d", oldPos);
const HB_CharAttributes *attributes = d->attributes();
- if (!attributes)
- return 0;
- int len = d->block.isValid() ?
- (d->block.length() - 1)
- : d->layoutData->string.length();
-
- if (oldPos >= len)
+ int len = d->block.isValid() ? d->block.length() - 1
+ : d->layoutData->string.length();
+ Q_ASSERT(len <= d->layoutData->string.length());
+ if (!attributes || oldPos < 0 || oldPos >= len)
return oldPos;
+
if (mode == SkipCharacters) {
oldPos++;
while (oldPos < len && !attributes[oldPos].charStop)
@@ -679,22 +690,23 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
while (oldPos < len && d->atSpace(oldPos))
oldPos++;
}
-// qDebug(" -> %d", oldPos);
+
return oldPos;
}
/*!
Returns the first valid cursor position before \a oldPos that
respects the given cursor \a mode.
+ Returns value of \a oldPos, if \a oldPos is not a valid cursor position.
- \sa isValidCursorPosition() nextCursorPosition()
+ \sa isValidCursorPosition(), nextCursorPosition()
*/
int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
{
-// qDebug("looking for previous cursor pos for %d", oldPos);
const HB_CharAttributes *attributes = d->attributes();
- if (!attributes || oldPos <= 0)
- return 0;
+ if (!attributes || oldPos <= 0 || oldPos > d->layoutData->string.length())
+ return oldPos;
+
if (mode == SkipCharacters) {
oldPos--;
while (oldPos && !attributes[oldPos].charStop)
@@ -712,7 +724,7 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
oldPos--;
}
}
-// qDebug(" -> %d", oldPos);
+
return oldPos;
}
@@ -739,7 +751,6 @@ bool QTextLayout::isValidCursorPosition(int pos) const
return attributes[pos].charStop;
}
-
/*!
Returns a new text line to be laid out if there is text to be
inserted into the layout; otherwise returns an invalid text line.
@@ -801,7 +812,7 @@ int QTextLayout::lineCount() const
/*!
Returns the \a{i}-th line of text in this text layout.
- \sa lineCount() lineForTextPosition()
+ \sa lineCount(), lineForTextPosition()
*/
QTextLine QTextLayout::lineAt(int i) const
{
@@ -811,7 +822,7 @@ QTextLine QTextLayout::lineAt(int i) const
/*!
Returns the line that contains the cursor position specified by \a pos.
- \sa isValidCursorPosition() lineAt()
+ \sa isValidCursorPosition(), lineAt()
*/
QTextLine QTextLayout::lineForTextPosition(int pos) const
{
@@ -902,8 +913,9 @@ qreal QTextLayout::maximumWidth() const
return d->maxWidth.toReal();
}
+
/*!
- \internal
+ \internal
*/
void QTextLayout::setFlags(int flags)
{
@@ -1028,6 +1040,35 @@ QScriptItem &QTextLineItemIterator::next()
return *si;
}
+static QFixed offsetInLigature(const unsigned short *logClusters,
+ const QGlyphLayout &glyphs,
+ int pos, int max, int glyph_pos)
+{
+ int offsetInCluster = 0;
+ for (int i = pos - 1; i >= 0; i--) {
+ if (logClusters[i] == glyph_pos)
+ offsetInCluster++;
+ else
+ break;
+ }
+
+ // in the case that the offset is inside a (multi-character) glyph,
+ // interpolate the position.
+ if (offsetInCluster > 0) {
+ int clusterLength = 0;
+ for (int i = pos - offsetInCluster; i < max; i++) {
+ if (logClusters[i] == glyph_pos)
+ clusterLength++;
+ else
+ break;
+ }
+ if (clusterLength)
+ return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
+ }
+
+ return 0;
+}
+
bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
{
*selectionX = *selectionWidth = 0;
@@ -1067,8 +1108,19 @@ bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selec
swidth += glyphs.effectiveAdvance(g);
}
- *selectionX = x + soff;
- *selectionWidth = swidth;
+ // If the starting character is in the middle of a ligature,
+ // selection should only contain the right part of that ligature
+ // glyph, so we need to get the width of the left part here and
+ // add it to *selectionX
+ QFixed leftOffsetInLigature = offsetInLigature(logClusters, glyphs, from,
+ to, start_glyph);
+ *selectionX = x + soff + leftOffsetInLigature;
+ *selectionWidth = swidth - leftOffsetInLigature;
+ // If the ending character is also part of a ligature, swidth does
+ // not contain that part yet, we also need to find out the width of
+ // that left part
+ *selectionWidth += offsetInLigature(logClusters, glyphs, to,
+ eng->length(item), end_glyph);
}
return true;
}
@@ -1114,9 +1166,26 @@ static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
return clip.isValid() ? (rect & clip) : rect;
}
+
/*!
- Draws the whole layout on the painter \a p at the position specified by
- \a pos.
+ Returns the glyph indexes and positions for all glyphs in this QTextLayout. This is an
+ expensive function, and should not be called in a time sensitive context.
+
+ \since 4.8
+
+ \sa draw(), QPainter::drawGlyphs()
+*/
+QList<QGlyphs> QTextLayout::glyphs() const
+{
+ QList<QGlyphs> glyphs;
+ for (int i=0; i<d->lines.size(); ++i)
+ glyphs += QTextLine(i, d).glyphs(-1, -1);
+
+ return glyphs;
+}
+
+/*!
+ Draws the whole layout on the painter \a p at the position specified by \a pos.
The rendered layout includes the given \a selections and is clipped within
the rectangle specified by \a clip.
*/
@@ -1290,12 +1359,12 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
}
/*!
- \fn void QTextLayout::drawCursor(QPainter *painter, const QPointF &position, int cursorPosition) const
- \overload
+ \fn void QTextLayout::drawCursor(QPainter *painter, const QPointF &position, int cursorPosition) const
+ \overload
- Draws a text cursor with the current pen at the given \a position using the
- \a painter specified.
- The corresponding position within the text is specified by \a cursorPosition.
+ Draws a text cursor with the current pen at the given \a position using the
+ \a painter specified.
+ The corresponding position within the text is specified by \a cursorPosition.
*/
void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition) const
{
@@ -1303,11 +1372,11 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
}
/*!
- \fn void QTextLayout::drawCursor(QPainter *painter, const QPointF &position, int cursorPosition, int width) const
+ \fn void QTextLayout::drawCursor(QPainter *painter, const QPointF &position, int cursorPosition, int width) const
- Draws a text cursor with the current pen and the specified \a width at the given \a position using the
- \a painter specified.
- The corresponding position within the text is specified by \a cursorPosition.
+ Draws a text cursor with the current pen and the specified \a width at the given \a position using the
+ \a painter specified.
+ The corresponding position within the text is specified by \a cursorPosition.
*/
void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition, int width) const
{
@@ -1438,7 +1507,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
/*!
Returns the line's bounding rectangle.
- \sa x() y() textLength() width()
+ \sa x(), y(), textLength(), width()
*/
QRectF QTextLine::rect() const
{
@@ -1464,7 +1533,7 @@ QRectF QTextLine::naturalTextRect() const
/*!
Returns the line's x position.
- \sa rect() y() textLength() width()
+ \sa rect(), y(), textLength(), width()
*/
qreal QTextLine::x() const
{
@@ -1474,7 +1543,7 @@ qreal QTextLine::x() const
/*!
Returns the line's y position.
- \sa x() rect() textLength() width()
+ \sa x(), rect(), textLength(), width()
*/
qreal QTextLine::y() const
{
@@ -1484,7 +1553,7 @@ qreal QTextLine::y() const
/*!
Returns the line's width as specified by the layout() function.
- \sa naturalTextWidth() x() y() textLength() rect()
+ \sa naturalTextWidth(), x(), y(), textLength(), rect()
*/
qreal QTextLine::width() const
{
@@ -1495,7 +1564,7 @@ qreal QTextLine::width() const
/*!
Returns the line's ascent.
- \sa descent() height()
+ \sa descent(), height()
*/
qreal QTextLine::ascent() const
{
@@ -1505,7 +1574,7 @@ qreal QTextLine::ascent() const
/*!
Returns the line's descent.
- \sa ascent() height()
+ \sa ascent(), height()
*/
qreal QTextLine::descent() const
{
@@ -1517,7 +1586,7 @@ qreal QTextLine::descent() const
if leading is not included. If leading is included, this equals to
ascent() + descent() + leading() + 1.
- \sa ascent() descent() leading() setLeadingIncluded()
+ \sa ascent(), descent(), leading(), setLeadingIncluded()
*/
qreal QTextLine::height() const
{
@@ -1529,24 +1598,25 @@ qreal QTextLine::height() const
Returns the line's leading.
- \sa ascent() descent() height()
+ \sa ascent(), descent(), height()
*/
qreal QTextLine::leading() const
{
return eng->lines[i].leading.toReal();
}
-/*! \since 4.6
+/*!
+ \since 4.6
- Includes positive leading into the line's height if \a included is true;
- otherwise does not include leading.
+ Includes positive leading into the line's height if \a included is true;
+ otherwise does not include leading.
- By default, leading is not included.
+ By default, leading is not included.
- Note that negative leading is ignored, it must be handled
- in the code using the text lines by letting the lines overlap.
+ Note that negative leading is ignored, it must be handled
+ in the code using the text lines by letting the lines overlap.
- \sa leadingIncluded()
+ \sa leadingIncluded()
*/
void QTextLine::setLeadingIncluded(bool included)
@@ -1555,20 +1625,21 @@ void QTextLine::setLeadingIncluded(bool included)
}
-/*! \since 4.6
+/*!
+ \since 4.6
- Returns true if positive leading is included into the line's height; otherwise returns false.
+ Returns true if positive leading is included into the line's height;
+ otherwise returns false.
- By default, leading is not included.
+ By default, leading is not included.
- \sa setLeadingIncluded()
+ \sa setLeadingIncluded()
*/
bool QTextLine::leadingIncluded() const
{
return eng->lines[i].leadingIncluded;
}
-
/*!
Returns the width of the line that is occupied by text. This is
always \<= to width(), and is the minimum width that could be used
@@ -1579,14 +1650,15 @@ qreal QTextLine::naturalTextWidth() const
return eng->lines[i].textWidth.toReal();
}
-/*! \since 4.7
- Returns the horizontal advance of the text. The advance of the text
- is the distance from its position to the next position at which
- text would naturally be drawn.
+/*!
+ \since 4.7
+ Returns the horizontal advance of the text. The advance of the text
+ is the distance from its position to the next position at which
+ text would naturally be drawn.
- By adding the advance to the position of the text line and using this
- as the position of a second text line, you will be able to position
- the two lines side-by-side without gaps in-between.
+ By adding the advance to the position of the text line and using this
+ as the position of a second text line, you will be able to position
+ the two lines side-by-side without gaps in-between.
*/
qreal QTextLine::horizontalAdvance() const
{
@@ -1764,7 +1836,8 @@ static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &gly
++line.length;
} while (pos < end && logClusters[pos] == glyphPosition);
do { // calculate the textWidth for the rest of the current cluster.
- line.textWidth += glyphs.advances_x[glyphPosition] * !glyphs.attributes[glyphPosition].dontPrint;
+ if (!glyphs.attributes[glyphPosition].dontPrint)
+ line.textWidth += glyphs.advances_x[glyphPosition];
++glyphPosition;
} while (glyphPosition < current.num_glyphs && !glyphs.attributes[glyphPosition].clusterStart);
@@ -1842,14 +1915,14 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.currentPosition = qMax(line.from, current.position);
end = current.position + eng->length(item);
lbh.glyphs = eng->shapedGlyphs(&current);
+ QFontEngine *fontEngine = eng->fontEngine(current);
+ if (lbh.fontEngine != fontEngine) {
+ lbh.fontEngine = fontEngine;
+ lbh.minimumRightBearing = qMin(QFixed(),
+ QFixed::fromReal(fontEngine->minRightBearing()));
+ }
}
const QScriptItem &current = eng->layoutData->items[item];
- QFontEngine *fontEngine = eng->fontEngine(current);
- if (lbh.fontEngine != fontEngine) {
- lbh.fontEngine = fontEngine;
- lbh.minimumRightBearing = qMin(QFixed(),
- QFixed::fromReal(fontEngine->minRightBearing()));
- }
lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
@@ -2014,9 +2087,10 @@ found:
eng->maxWidth += lbh.spaceData.textWidth;
if (eng->option.flags() & QTextOption::IncludeTrailingSpaces)
line.textWidth += lbh.spaceData.textWidth;
- line.length += lbh.spaceData.length;
- if (lbh.spaceData.length)
+ if (lbh.spaceData.length) {
+ line.length += lbh.spaceData.length;
line.hasTrailingSpaces = true;
+ }
line.justified = false;
line.gridfitted = false;
@@ -2170,6 +2244,151 @@ static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const Q
}
+namespace {
+ struct GlyphInfo
+ {
+ GlyphInfo(const QGlyphLayout &layout, const QPointF &position,
+ const QTextItemInt::RenderFlags &renderFlags)
+ : glyphLayout(layout), itemPosition(position), flags(renderFlags)
+ {
+ }
+
+ QGlyphLayout glyphLayout;
+ QPointF itemPosition;
+ QTextItem::RenderFlags flags;
+ };
+}
+
+/*!
+ \internal
+
+ Returns the glyph indexes and positions for all glyphs in this QTextLine which reside in
+ QScriptItems that overlap with the range defined by \a from and \a length. The arguments
+ specify characters, relative to the text in the layout. Note that it is not possible to
+ use this function to retrieve a subset of the glyphs in a QScriptItem.
+
+ \since 4.8
+
+ \sa QTextLayout::glyphs()
+*/
+QList<QGlyphs> QTextLine::glyphs(int from, int length) const
+{
+ const QScriptLine &line = eng->lines[i];
+
+ if (line.length == 0)
+ return QList<QGlyphs>();
+
+ QHash<QFontEngine *, GlyphInfo> glyphLayoutHash;
+
+ QTextLineItemIterator iterator(eng, i);
+ qreal y = line.y.toReal() + line.base().toReal();
+ while (!iterator.atEnd()) {
+ QScriptItem &si = iterator.next();
+ if (si.analysis.flags >= QScriptAnalysis::TabOrObject)
+ continue;
+
+ QPointF pos(iterator.x.toReal(), y);
+ if (from >= 0 && length >= 0 &&
+ (from >= si.position + eng->length(&si) || from + length <= si.position))
+ continue;
+
+ QFont font = eng->font(si);
+
+ QTextItem::RenderFlags flags;
+ if (font.overline())
+ flags |= QTextItem::Overline;
+ if (font.underline())
+ flags |= QTextItem::Underline;
+ if (font.strikeOut())
+ flags |= QTextItem::StrikeOut;
+ if (si.analysis.bidiLevel % 2)
+ flags |= QTextItem::RightToLeft;
+
+ QGlyphLayout glyphLayout = eng->shapedGlyphs(&si).mid(iterator.glyphsStart,
+ iterator.glyphsEnd - iterator.glyphsStart);
+
+ if (glyphLayout.numGlyphs > 0) {
+ QFontEngine *mainFontEngine = font.d->engineForScript(si.analysis.script);
+ if (mainFontEngine->type() == QFontEngine::Multi) {
+ QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine);
+ int start = 0;
+ int end;
+ int which = glyphLayout.glyphs[0] >> 24;
+ for (end = 0; end < glyphLayout.numGlyphs; ++end) {
+ const int e = glyphLayout.glyphs[end] >> 24;
+ if (e == which)
+ continue;
+
+ QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
+ glyphLayoutHash.insertMulti(multiFontEngine->engine(which),
+ GlyphInfo(subLayout, pos, flags));
+
+ start = end;
+ which = e;
+ }
+
+ QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
+ glyphLayoutHash.insertMulti(multiFontEngine->engine(which),
+ GlyphInfo(subLayout, pos, flags));
+
+ } else {
+ glyphLayoutHash.insertMulti(mainFontEngine,
+ GlyphInfo(glyphLayout, pos, flags));
+ }
+ }
+ }
+
+ QHash<QPair<QFontEngine *, int>, QGlyphs> glyphsHash;
+
+ QList<QFontEngine *> keys = glyphLayoutHash.uniqueKeys();
+ for (int i=0; i<keys.size(); ++i) {
+ QFontEngine *fontEngine = keys.at(i);
+
+ // Make a font for this particular engine
+ QFont font = fontEngine->createExplicitFont();
+
+ QList<GlyphInfo> glyphLayouts = glyphLayoutHash.values(fontEngine);
+ for (int j=0; j<glyphLayouts.size(); ++j) {
+ const QPointF &pos = glyphLayouts.at(j).itemPosition;
+ const QGlyphLayout &glyphLayout = glyphLayouts.at(j).glyphLayout;
+ const QTextItem::RenderFlags &flags = glyphLayouts.at(j).flags;
+
+ font.setOverline(flags.testFlag(QTextItem::Overline));
+ font.setUnderline(flags.testFlag(QTextItem::Underline));
+ font.setStrikeOut(flags.testFlag(QTextItem::StrikeOut));
+
+ QVarLengthArray<glyph_t> glyphsArray;
+ QVarLengthArray<QFixedPoint> positionsArray;
+
+ fontEngine->getGlyphPositions(glyphLayout, QTransform(), flags, glyphsArray,
+ positionsArray);
+ Q_ASSERT(glyphsArray.size() == positionsArray.size());
+
+ QVector<quint32> glyphs;
+ QVector<QPointF> positions;
+ for (int i=0; i<glyphsArray.size(); ++i) {
+ glyphs.append(glyphsArray.at(i) & 0xffffff);
+ positions.append(positionsArray.at(i).toPointF() + pos);
+ }
+
+ QGlyphs glyphIndexes;
+ glyphIndexes.setGlyphIndexes(glyphs);
+ glyphIndexes.setPositions(positions);
+
+ QPair<QFontEngine *, int> key(fontEngine, int(flags));
+
+ if (!glyphsHash.contains(key))
+ glyphsHash.insert(key, QGlyphs());
+
+ QGlyphs &target = glyphsHash[key];
+ target += glyphIndexes;
+ target.setFont(font);
+ }
+ }
+
+ return glyphsHash.values();
+}
+
/*!
\fn void QTextLine::draw(QPainter *painter, const QPointF &position, const QTextLayout::FormatRange *selection) const
@@ -2366,21 +2585,20 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
}
/*!
- \fn int QTextLine::cursorToX(int cursorPos, Edge edge) const
+ \fn int QTextLine::cursorToX(int cursorPos, Edge edge) const
- \overload
+ \overload
*/
-
/*!
- Converts the cursor position \a cursorPos to the corresponding x position
- inside the line, taking account of the \a edge.
+ Converts the cursor position \a cursorPos to the corresponding x position
+ inside the line, taking account of the \a edge.
- If \a cursorPos is not a valid cursor position, the nearest valid
- cursor position will be used instead, and cpos will be modified to
- point to this valid cursor position.
+ If \a cursorPos is not a valid cursor position, the nearest valid
+ cursor position will be used instead, and cpos will be modified to
+ point to this valid cursor position.
- \sa xToCursor()
+ \sa xToCursor()
*/
qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
{
@@ -2479,14 +2697,6 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
if(pos == l)
x += si->width;
} else {
- int offsetInCluster = 0;
- for (int i=pos-1; i >= 0; i--) {
- if (logClusters[i] == glyph_pos)
- offsetInCluster++;
- else
- break;
- }
-
if (reverse) {
int end = qMin(lineEnd, si->position + l) - si->position;
int glyph_end = end == l ? si->num_glyphs : logClusters[end];
@@ -2498,17 +2708,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
for (int i = glyph_start; i < glyph_pos; i++)
x += glyphs.effectiveAdvance(i);
}
- if (offsetInCluster > 0) { // in the case that the offset is inside a (multi-character) glyph, interpolate the position.
- int clusterLength = 0;
- for (int i=pos - offsetInCluster; i < line.length; i++) {
- if (logClusters[i] == glyph_pos)
- clusterLength++;
- else
- break;
- }
- if (clusterLength)
- x+= glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
- }
+ x += offsetInLigature(logClusters, glyphs, pos, line.length, glyph_pos);
}
*cursorPos = pos + si->position;
@@ -2516,12 +2716,12 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
}
/*!
- \fn int QTextLine::xToCursor(qreal x, CursorPosition cpos) const
+ \fn int QTextLine::xToCursor(qreal x, CursorPosition cpos) const
- Converts the x-coordinate \a x, to the nearest matching cursor
- position, depending on the cursor position type, \a cpos.
+ Converts the x-coordinate \a x, to the nearest matching cursor
+ position, depending on the cursor position type, \a cpos.
- \sa cursorToX()
+ \sa cursorToX()
*/
int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
{
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index 8c93ed65b6..32d6d0eaf0 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -49,6 +49,7 @@
#include <QtCore/qobject.h>
#include <QtGui/qevent.h>
#include <QtGui/qtextformat.h>
+#include <QtGui/qglyphs.h>
QT_BEGIN_HEADER
@@ -166,6 +167,8 @@ public:
qreal minimumWidth() const;
qreal maximumWidth() const;
+ QList<QGlyphs> glyphs() const;
+
QTextEngine *engine() const { return d; }
void setFlags(int flags);
private:
@@ -236,7 +239,10 @@ public:
private:
QTextLine(int line, QTextEngine *e) : i(line), eng(e) {}
void layout_helper(int numGlyphs);
+ QList<QGlyphs> glyphs(int from, int length) const;
+
friend class QTextLayout;
+ friend class QTextFragment;
int i;
QTextEngine *eng;
};
diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp
index a0ff52043a..c312d89d82 100644
--- a/src/gui/text/qtextlist.cpp
+++ b/src/gui/text/qtextlist.cpp
@@ -191,6 +191,13 @@ QString QTextList::itemText(const QTextBlock &blockIt) const
QString result;
const int style = format().style();
+ QString numberPrefix;
+ QString numberSuffix = QLatin1String(".");
+
+ if (format().hasProperty(QTextFormat::ListNumberPrefix))
+ numberPrefix = format().numberPrefix();
+ if (format().hasProperty(QTextFormat::ListNumberSuffix))
+ numberSuffix = format().numberSuffix();
switch (style) {
case QTextListFormat::ListDecimal:
@@ -232,7 +239,7 @@ QString QTextList::itemText(const QTextBlock &blockIt) const
if (q > 0) {
int startDigit = i + (i+3)/4;
int numDigits;
- if (i % 4) {
+ if (i % 4) {
// c[i] == 4|5|9|40|50|90|400|500|900
if ((i-2) % 4) {
// c[i] == 4|9|40|90|400|900 => with substraction (IV, IX, XL, XC, ...)
@@ -263,8 +270,9 @@ QString QTextList::itemText(const QTextBlock &blockIt) const
Q_ASSERT(false);
}
if (blockIt.textDirection() == Qt::RightToLeft)
- return result.prepend(QLatin1Char('.'));
- return result + QLatin1Char('.');
+ return numberSuffix + result + numberPrefix;
+ else
+ return numberPrefix + result + numberSuffix;
}
/*!
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index ea2ef2d6ad..65fd36e938 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -1655,6 +1655,35 @@ QTextBlock::iterator &QTextBlock::iterator::operator--()
than the \a other text fragment; otherwise returns false.
*/
+/*!
+ Returns the glyphs of this text fragment. The positions of the glyphs are
+ relative to the position of the QTextBlock's layout.
+
+ \sa QGlyphs, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphs()
+*/
+QList<QGlyphs> QTextFragment::glyphs() const
+{
+ if (!p || !n)
+ return QList<QGlyphs>();
+
+ int pos = position();
+ int len = length();
+ if (len == 0)
+ return QList<QGlyphs>();
+
+ int blockNode = p->blockMap().findNode(pos);
+
+ const QTextBlockData *blockData = p->blockMap().fragment(blockNode);
+ QTextLayout *layout = blockData->layout;
+
+ QList<QGlyphs> ret;
+ for (int i=0; i<layout->lineCount(); ++i) {
+ QTextLine textLine = layout->lineAt(i);
+ ret += textLine.glyphs(pos, len);
+ }
+
+ return ret;
+}
/*!
Returns the position of this text fragment in the document.
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index a573a263ac..332458db9b 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtGui/qtextformat.h>
+#include <QtGui/qglyphs.h>
QT_BEGIN_HEADER
@@ -315,6 +316,8 @@ public:
int charFormatIndex() const;
QString text() const;
+ QList<QGlyphs> glyphs() const;
+
private:
const QTextDocumentPrivate *p;
int n;
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 7992de515c..04f6913825 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -636,7 +636,15 @@ void QTextOdfWriter::writeListFormat(QXmlStreamWriter &writer, QTextListFormat f
|| style == QTextListFormat::ListUpperRoman) {
writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-number"));
writer.writeAttribute(styleNS, QString::fromLatin1("num-format"), bulletChar(style));
- writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), QString::fromLatin1("."));
+
+ if (format.hasProperty(QTextFormat::ListNumberSuffix))
+ writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), format.numberSuffix());
+ else
+ writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), QString::fromLatin1("."));
+
+ if (format.hasProperty(QTextFormat::ListNumberPrefix))
+ writer.writeAttribute(styleNS, QString::fromLatin1("num-prefix"), format.numberPrefix());
+
} else {
writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-bullet"));
writer.writeAttribute(textNS, QString::fromLatin1("bullet-char"), bulletChar(style));
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index af8daa5d99..102df4d41d 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -39,7 +39,9 @@ HEADERS += \
text/qzipwriter_p.h \
text/qtextodfwriter_p.h \
text/qstatictext_p.h \
- text/qstatictext.h
+ text/qstatictext.h \
+ text/qglyphs.h \
+ text/qglyphs_p.h
SOURCES += \
text/qfont.cpp \
@@ -69,7 +71,8 @@ SOURCES += \
text/qcssparser.cpp \
text/qzip.cpp \
text/qtextodfwriter.cpp \
- text/qstatictext.cpp
+ text/qstatictext.cpp \
+ text/qglyphs.cpp
win32 {
SOURCES += \
diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp
index 995d6597a1..bd66843494 100644
--- a/src/gui/widgets/qabstractbutton.cpp
+++ b/src/gui/widgets/qabstractbutton.cpp
@@ -319,7 +319,7 @@ QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const
return group->d_func()->buttonList;
#endif
- QList<QAbstractButton*>candidates = qFindChildren<QAbstractButton *>(parent);
+ QList<QAbstractButton*>candidates = parent->findChildren<QAbstractButton *>();
if (autoExclusive) {
for (int i = candidates.count() - 1; i >= 0; --i) {
QAbstractButton *candidate = candidates.at(i);
diff --git a/src/gui/widgets/qcheckbox.cpp b/src/gui/widgets/qcheckbox.cpp
index bc0900e94e..64b47b4d08 100644
--- a/src/gui/widgets/qcheckbox.cpp
+++ b/src/gui/widgets/qcheckbox.cpp
@@ -300,6 +300,15 @@ QSize QCheckBox::sizeHint() const
return d->sizeHint;
}
+
+/*!
+ \reimp
+*/
+QSize QCheckBox::minimumSizeHint() const
+{
+ return sizeHint();
+}
+
/*!
\reimp
*/
diff --git a/src/gui/widgets/qcheckbox.h b/src/gui/widgets/qcheckbox.h
index 7b6292d616..95da2612a4 100644
--- a/src/gui/widgets/qcheckbox.h
+++ b/src/gui/widgets/qcheckbox.h
@@ -65,6 +65,7 @@ public:
QSize sizeHint() const;
+ QSize minimumSizeHint() const;
void setTristate(bool y = true);
bool isTristate() const;
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 96d2acdd06..21dd127f98 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -116,7 +116,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
QPalette resolvedpalette = option.palette.resolve(QApplication::palette("QMenu"));
QVariant value = index.data(Qt::ForegroundRole);
- if (qVariantCanConvert<QBrush>(value)) {
+ if (value.canConvert<QBrush>()) {
resolvedpalette.setBrush(QPalette::WindowText, qvariant_cast<QBrush>(value));
resolvedpalette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(value));
resolvedpalette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
@@ -152,7 +152,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
menuOption.icon = qvariant_cast<QPixmap>(variant);
break;
}
- if (qVariantCanConvert<QBrush>(index.data(Qt::BackgroundRole))) {
+ if (index.data(Qt::BackgroundRole).canConvert<QBrush>()) {
menuOption.palette.setBrush(QPalette::All, QPalette::Background,
qvariant_cast<QBrush>(index.data(Qt::BackgroundRole)));
}
@@ -369,6 +369,7 @@ void QComboBoxPrivateContainer::timerEvent(QTimerEvent *timerEvent)
if (timerEvent->timerId() == adjustSizeTimer.timerId()) {
adjustSizeTimer.stop();
if (combo->sizeAdjustPolicy() == QComboBox::AdjustToContents) {
+ combo->updateGeometry();
combo->adjustSize();
combo->update();
}
@@ -1298,7 +1299,7 @@ QComboBox::~QComboBox()
By default, this property has a value of 10.
\note This property is ignored for non-editable comboboxes in styles that returns
- false for QStyle::SH_ComboBox_Popup such as the Mac style or the Gtk+ Style.
+ true for QStyle::SH_ComboBox_Popup such as the Mac style or the Gtk+ Style.
*/
int QComboBox::maxVisibleItems() const
{
@@ -2008,11 +2009,18 @@ void QComboBox::setCurrentIndex(int index)
void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
{
Q_Q(QComboBox);
- bool indexChanged = (mi != currentIndex);
+
+ QModelIndex normalized;
+ if (mi.column() != modelColumn)
+ normalized = model->index(mi.row(), modelColumn, mi.parent());
+ if (!normalized.isValid())
+ normalized = mi; // Fallback to passed index.
+
+ bool indexChanged = (normalized != currentIndex);
if (indexChanged)
- currentIndex = QPersistentModelIndex(mi);
+ currentIndex = QPersistentModelIndex(normalized);
if (lineEdit) {
- QString newText = q->itemText(currentIndex.row());
+ QString newText = q->itemText(normalized.row());
if (lineEdit->text() != newText)
lineEdit->setText(newText);
updateLineEditGeometry();
diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h
index fb9af9ff99..81a4389c25 100644
--- a/src/gui/widgets/qcombobox.h
+++ b/src/gui/widgets/qcombobox.h
@@ -68,7 +68,7 @@ class Q_GUI_EXPORT QComboBox : public QWidget
Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
Q_PROPERTY(int count READ count)
Q_PROPERTY(QString currentText READ currentText)
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged USER true)
Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount)
Q_PROPERTY(InsertPolicy insertPolicy READ insertPolicy WRITE setInsertPolicy)
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
index 29a628cbf0..c0727ed016 100644
--- a/src/gui/widgets/qcombobox_p.h
+++ b/src/gui/widgets/qcombobox_p.h
@@ -337,7 +337,7 @@ private:
QComboBox *mCombo;
};
-class QComboBoxPrivate : public QWidgetPrivate
+class Q_AUTOTEST_EXPORT QComboBoxPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QComboBox)
public:
diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp
index bd6c57703d..36a31478e7 100644
--- a/src/gui/widgets/qdatetimeedit.cpp
+++ b/src/gui/widgets/qdatetimeedit.cpp
@@ -890,7 +890,13 @@ void QDateTimeEdit::setDisplayFormat(const QString &format)
const bool dateShown = (d->sections & DateSections_Mask);
Q_ASSERT(dateShown || timeShown);
if (timeShown && !dateShown) {
+ QTime time = d->value.toTime();
setDateRange(d->value.toDate(), d->value.toDate());
+ if (d->minimum.toTime() >= d->maximum.toTime()) {
+ setTimeRange(QDATETIMEEDIT_TIME_MIN, QDATETIMEEDIT_TIME_MAX);
+ // if the time range became invalid during the adjustment, the time would have been reset
+ setTime(time);
+ }
} else if (dateShown && !timeShown) {
setTimeRange(QDATETIMEEDIT_TIME_MIN, QDATETIMEEDIT_TIME_MAX);
d->value = QDateTime(d->value.toDate(), QTime(), d->spec);
@@ -1654,6 +1660,15 @@ void QDateTimeEditPrivate::updateTimeSpec()
minimum = minimum.toDateTime().toTimeSpec(spec);
maximum = maximum.toDateTime().toTimeSpec(spec);
value = value.toDateTime().toTimeSpec(spec);
+
+ // time zone changes can lead to 00:00:00 becomes 01:00:00 and 23:59:59 becomes 00:59:59 (invalid range)
+ const bool dateShown = (sections & QDateTimeEdit::DateSections_Mask);
+ if (!dateShown) {
+ if (minimum.toTime() >= maximum.toTime()){
+ minimum = QDateTime(value.toDate(), QDATETIMEEDIT_TIME_MIN, spec);
+ maximum = QDateTime(value.toDate(), QDATETIMEEDIT_TIME_MAX, spec);
+ }
+ }
}
void QDateTimeEditPrivate::updateEdit()
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 732dbc9cc8..9aea32a8ec 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -1229,7 +1229,7 @@ bool QDialogButtonBox::event(QEvent *event)
break;
}
- foreach (QPushButton *pb, qFindChildren<QPushButton *>(dialog ? dialog : this)) {
+ foreach (QPushButton *pb, (dialog ? dialog : this)->findChildren<QPushButton *>()) {
if (pb->isDefault() && pb != firstAcceptButton) {
hasDefault = true;
break;
diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp
index bdbd0b04ef..f5393a9218 100644
--- a/src/gui/widgets/qlabel.cpp
+++ b/src/gui/widgets/qlabel.cpp
@@ -1071,7 +1071,7 @@ void QLabel::paintEvent(QPaintEvent *)
else
#endif
if (d->isTextLabel) {
- QRectF lr = d->layoutRect();
+ QRectF lr = d->layoutRect().toAlignedRect();
QStyleOption opt;
opt.initFrom(this);
#ifndef QT_NO_STYLE_STYLESHEET
diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h
index 94e0dbe6dc..667562bcb4 100644
--- a/src/gui/widgets/qlineedit.h
+++ b/src/gui/widgets/qlineedit.h
@@ -283,6 +283,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool))
#endif
Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &))
};
#endif // QT_NO_LINEEDIT
diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp
index 468c111093..d705fa8e6b 100644
--- a/src/gui/widgets/qlineedit_p.cpp
+++ b/src/gui/widgets/qlineedit_p.cpp
@@ -59,6 +59,13 @@ QT_BEGIN_NAMESPACE
const int QLineEditPrivate::verticalMargin(1);
const int QLineEditPrivate::horizontalMargin(2);
+QRect QLineEditPrivate::adjustedControlRect(const QRect &rect) const
+{
+ QRect cr = adjustedContentsRect();
+ int cix = cr.x() - hscroll + horizontalMargin;
+ return rect.translated(QPoint(cix, vscroll));
+}
+
int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
{
QRect cr = adjustedContentsRect();
@@ -68,11 +75,7 @@ int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
QRect QLineEditPrivate::cursorRect() const
{
- QRect cr = adjustedContentsRect();
- int cix = cr.x() - hscroll + horizontalMargin;
- QRect crect = control->cursorRect();
- crect.moveTo(crect.topLeft() + QPoint(cix, vscroll));
- return crect;
+ return adjustedControlRect(control->cursorRect());
}
#ifndef QT_NO_COMPLETER
@@ -141,6 +144,11 @@ void QLineEditPrivate::_q_selectionChanged()
emit q->selectionChanged();
}
+void QLineEditPrivate::_q_updateNeeded(const QRect &rect)
+{
+ q_func()->update(adjustedControlRect(rect));
+}
+
void QLineEditPrivate::init(const QString& txt)
{
Q_Q(QLineEdit);
@@ -176,7 +184,7 @@ void QLineEditPrivate::init(const QString& txt)
q, SLOT(update()));
QObject::connect(control, SIGNAL(updateNeeded(QRect)),
- q, SLOT(update()));
+ q, SLOT(_q_updateNeeded(QRect)));
QStyleOptionFrameV2 opt;
q->initStyleOption(&opt);
@@ -216,9 +224,8 @@ void QLineEditPrivate::setCursorVisible(bool visible)
if ((bool)cursorVisible == visible)
return;
cursorVisible = visible;
- QRect r = cursorRect();
if (control->inputMask().isEmpty())
- q->update(r);
+ q->update(cursorRect());
else
q->update();
}
diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h
index 7a24cb3016..b9f9c0bf94 100644
--- a/src/gui/widgets/qlineedit_p.h
+++ b/src/gui/widgets/qlineedit_p.h
@@ -94,6 +94,8 @@ public:
#endif
void init(const QString&);
+ QRect adjustedControlRect(const QRect &) const;
+
int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
QRect cursorRect() const;
void setCursorVisible(bool visible);
@@ -129,6 +131,7 @@ public:
void _q_editFocusChange(bool);
#endif
void _q_selectionChanged();
+ void _q_updateNeeded(const QRect &);
#ifndef QT_NO_COMPLETER
void _q_completionHighlighted(QString);
#endif
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 1183be6301..4ca11b039f 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -1634,7 +1634,7 @@ QMenu *QMainWindow::createPopupMenu()
Q_D(QMainWindow);
QMenu *menu = 0;
#ifndef QT_NO_DOCKWIDGET
- QList<QDockWidget *> dockwidgets = qFindChildren<QDockWidget *>(this);
+ QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
if (dockwidgets.size()) {
menu = new QMenu(this);
for (int i = 0; i < dockwidgets.size(); ++i) {
@@ -1648,7 +1648,7 @@ QMenu *QMainWindow::createPopupMenu()
}
#endif // QT_NO_DOCKWIDGET
#ifndef QT_NO_TOOLBAR
- QList<QToolBar *> toolbars = qFindChildren<QToolBar *>(this);
+ QList<QToolBar *> toolbars = findChildren<QToolBar *>();
if (toolbars.size()) {
if (!menu)
menu = new QMenu(this);
diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp
index 62d297e90f..3f4cdc3f13 100644
--- a/src/gui/widgets/qmdisubwindow.cpp
+++ b/src/gui/widgets/qmdisubwindow.cpp
@@ -2203,7 +2203,7 @@ void QMdiSubWindowPrivate::setSizeGrip(QSizeGrip *newSizeGrip)
void QMdiSubWindowPrivate::setSizeGripVisible(bool visible) const
{
// See if we can find any size grips
- QList<QSizeGrip *> sizeGrips = qFindChildren<QSizeGrip *>(q_func());
+ QList<QSizeGrip *> sizeGrips = q_func()->findChildren<QSizeGrip *>();
foreach (QSizeGrip *grip, sizeGrips)
grip->setVisible(visible);
}
@@ -2319,7 +2319,7 @@ void QMdiSubWindow::setWidget(QWidget *widget)
widget->setParent(this);
#ifndef QT_NO_SIZEGRIP
- QSizeGrip *sizeGrip = qFindChild<QSizeGrip *>(widget);
+ QSizeGrip *sizeGrip = widget->findChild<QSizeGrip *>();
if (sizeGrip)
sizeGrip->installEventFilter(this);
if (d->sizeGrip)
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 4bea6de0e2..245657a618 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -2804,7 +2804,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e)
if (d->sloppyRegion.contains(e->pos())) {
d->sloppyAction = action;
QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6);
- } else {
+ } else if (action != d->currentAction) {
d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this));
}
}
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index aaa113be55..60023a8a5e 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -1254,15 +1254,11 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction
NSString *keySequenceToKeyEqivalent(const QKeySequence &accel)
{
quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL));
- extern QChar qt_macSymbolForQtKey(int key); // qkeysequence.cpp
- QChar keyEquiv = qt_macSymbolForQtKey(accel_key);
- if (keyEquiv.isNull()) {
- if (accel_key >= Qt::Key_F1 && accel_key <= Qt::Key_F15)
- keyEquiv = (accel_key - Qt::Key_F1) + NSF1FunctionKey;
- else
- keyEquiv = unichar(QChar(accel_key).toLower().unicode());
- }
- return [NSString stringWithCharacters:&keyEquiv.unicode() length:1];
+ extern QChar qtKey2CocoaKey(Qt::Key key);
+ QChar cocoa_key = qtKey2CocoaKey(Qt::Key(accel_key));
+ if (cocoa_key.isNull())
+ cocoa_key = QChar(accel_key).toLower().unicode();
+ return [NSString stringWithCharacters:&cocoa_key.unicode() length:1];
}
// return the cocoa modifier mask for the QKeySequence (currently only looks at the first one).
@@ -2052,8 +2048,7 @@ bool QMenuBar::macUpdateMenuBar()
{
#ifdef QT_MAC_USE_COCOA
QMacCocoaAutoReleasePool pool;
- if (!qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar)))
- return QMenuBarPrivate::macUpdateMenuBarImmediatly();
+ qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar));
return true;
#else
return QMenuBarPrivate::macUpdateMenuBarImmediatly();
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index 83ba15ab52..652e65c8fe 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -264,7 +264,8 @@ void qt_symbian_show_submenu( CEikMenuPane* menuPane, int id)
// However if we don't have any items, we still need the item array. Otherwise
// menupane will crash. That's why we create item array here manually, and
// AddMenuItemL will then use the existing array.
- CEikMenuPane::CItemArray* itemArray = q_check_ptr(new CEikMenuPane::CItemArray);
+ CEikMenuPane::CItemArray* itemArray = new CEikMenuPane::CItemArray;
+ Q_CHECK_PTR(itemArray);
menuPane->SetItemArray(itemArray);
menuPane->SetItemArrayOwnedExternally(EFalse);
diff --git a/src/gui/widgets/qmenu_wince.cpp b/src/gui/widgets/qmenu_wince.cpp
index e088db6172..15d0116ac3 100644
--- a/src/gui/widgets/qmenu_wince.cpp
+++ b/src/gui/widgets/qmenu_wince.cpp
@@ -113,8 +113,6 @@ static void resolveAygLibs()
if (!aygResolved) {
aygResolved = true;
QLibrary aygLib(QLatin1String("aygshell"));
- if (!aygLib.load())
- return;
ptrCreateMenuBar = (AygCreateMenuBar) aygLib.resolve("SHCreateMenuBar");
ptrEnableSoftKey = (AygEnableSoftKey) aygLib.resolve("SHEnableSoftkey");
}
diff --git a/src/gui/widgets/qradiobutton.cpp b/src/gui/widgets/qradiobutton.cpp
index 20b6c7202e..56bd709193 100644
--- a/src/gui/widgets/qradiobutton.cpp
+++ b/src/gui/widgets/qradiobutton.cpp
@@ -207,6 +207,14 @@ QSize QRadioButton::sizeHint() const
/*!
\reimp
*/
+QSize QRadioButton::minimumSizeHint() const
+{
+ return sizeHint();
+}
+
+/*!
+ \reimp
+*/
bool QRadioButton::hitButton(const QPoint &pos) const
{
QStyleOptionButton opt;
diff --git a/src/gui/widgets/qradiobutton.h b/src/gui/widgets/qradiobutton.h
index 887b747b9d..b7031e276b 100644
--- a/src/gui/widgets/qradiobutton.h
+++ b/src/gui/widgets/qradiobutton.h
@@ -62,6 +62,7 @@ public:
explicit QRadioButton(const QString &text, QWidget *parent=0);
QSize sizeHint() const;
+ QSize minimumSizeHint() const;
protected:
bool event(QEvent *e);
diff --git a/src/gui/widgets/qsizegrip.cpp b/src/gui/widgets/qsizegrip.cpp
index c9d613a4f5..b5b611c169 100644
--- a/src/gui/widgets/qsizegrip.cpp
+++ b/src/gui/widgets/qsizegrip.cpp
@@ -78,15 +78,6 @@ static QWidget *qt_sizegrip_topLevelWidget(QWidget* w)
return w;
}
-static inline bool hasHeightForWidth(QWidget *widget)
-{
- if (!widget)
- return false;
- if (QLayout *layout = widget->layout())
- return layout->hasHeightForWidth();
- return widget->sizePolicy().hasHeightForWidth();
-}
-
class QSizeGripPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QSizeGrip)
@@ -318,7 +309,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e)
#ifdef Q_WS_X11
// Use a native X11 sizegrip for "real" top-level windows if supported.
if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
- && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) {
+ && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
XEvent xev;
xev.xclient.type = ClientMessage;
xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE);
@@ -340,7 +331,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e)
}
#endif // Q_WS_X11
#ifdef Q_WS_WIN
- if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) {
+ if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
uint orientation = 0;
if (d->atBottom())
orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT;
@@ -429,12 +420,12 @@ void QSizeGrip::mouseMoveEvent(QMouseEvent * e)
#ifdef Q_WS_X11
if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
- && tlw->isTopLevel() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw))
+ && tlw->isTopLevel() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth())
return;
#endif
#ifdef Q_WS_WIN
if (tlw->isWindow() && GetSystemMenu(tlw->winId(), FALSE) != 0 && internalWinId()
- && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) {
+ && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
MSG msg;
while(PeekMessage(&msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
return;
diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp
index 2d871d0e27..10ce144eda 100644
--- a/src/gui/widgets/qspinbox.cpp
+++ b/src/gui/widgets/qspinbox.cpp
@@ -697,6 +697,9 @@ void QDoubleSpinBox::setSuffix(const QString &suffix)
d->suffix = suffix;
d->updateEdit();
+
+ d->cachedSizeHint = QSize();
+ updateGeometry();
}
/*!
diff --git a/src/gui/widgets/qsplashscreen.cpp b/src/gui/widgets/qsplashscreen.cpp
index 8be0cf8902..2b6bfeb267 100644
--- a/src/gui/widgets/qsplashscreen.cpp
+++ b/src/gui/widgets/qsplashscreen.cpp
@@ -64,7 +64,6 @@ public:
int currAlign;
inline QSplashScreenPrivate();
- void drawContents();
};
/*!
@@ -121,10 +120,9 @@ public:
perhaps Qt::WindowStaysOnTopHint.
*/
QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f)
- : QWidget(*(new QSplashScreenPrivate()), 0, Qt::SplashScreen | f)
+ : QWidget(*(new QSplashScreenPrivate()), 0, Qt::SplashScreen | Qt::FramelessWindowHint | f)
{
- d_func()->pixmap = pixmap;
- setPixmap(d_func()->pixmap); // Does an implicit repaint
+ setPixmap(pixmap); // Does an implicit repaint
}
/*!
@@ -165,7 +163,6 @@ void QSplashScreen::mousePressEvent(QMouseEvent *)
*/
void QSplashScreen::repaint()
{
- d_func()->drawContents();
QWidget::repaint();
QApplication::flush();
}
@@ -234,23 +231,13 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap)
{
Q_D(QSplashScreen);
- if (pixmap.hasAlpha()) {
- QPixmap opaque(pixmap.size());
- QPainter p(&opaque);
- p.fillRect(0, 0, pixmap.width(), pixmap.height(), palette().background());
- p.drawPixmap(0, 0, pixmap);
- p.end();
- d->pixmap = opaque;
- } else {
- d->pixmap = pixmap;
- }
+ d->pixmap = pixmap;
+ setAttribute(Qt::WA_TranslucentBackground, pixmap.hasAlpha());
- QRect r(0, 0, d->pixmap.size().width(), d->pixmap.size().height());
- resize(d->pixmap.size());
+ QRect r(QPoint(), d->pixmap.size());
+ resize(r.size());
move(QApplication::desktop()->screenGeometry().center() - r.center());
- if (!isVisible())
- d->drawContents();
- else
+ if (isVisible())
repaint();
}
@@ -264,23 +251,6 @@ const QPixmap QSplashScreen::pixmap() const
}
/*!
- \internal
-*/
-void QSplashScreenPrivate::drawContents()
-{
- Q_Q(QSplashScreen);
- QPixmap textPix = pixmap;
- if (!textPix.isNull()) {
- QPainter painter(&textPix);
- painter.initFrom(q);
- q->drawContents(&painter);
- QPalette p = q->palette();
- p.setBrush(q->backgroundRole(), QBrush(textPix));
- q->setPalette(p);
- }
-}
-
-/*!
\internal
*/
inline QSplashScreenPrivate::QSplashScreenPrivate() : currAlign(Qt::AlignLeft)
@@ -297,8 +267,7 @@ void QSplashScreen::drawContents(QPainter *painter)
{
Q_D(QSplashScreen);
painter->setPen(d->currColor);
- QRect r = rect();
- r.setRect(r.x() + 5, r.y() + 5, r.width() - 10, r.height() - 10);
+ QRect r = rect().adjusted(5, 5, -5, -5);
if (Qt::mightBeRichText(d->currStatus)) {
QTextDocument doc;
#ifdef QT_NO_TEXTHTMLPARSER
@@ -339,6 +308,13 @@ void QSplashScreen::drawContents(QPainter *painter)
/*! \reimp */
bool QSplashScreen::event(QEvent *e)
{
+ if (e->type() == QEvent::Paint) {
+ Q_D(QSplashScreen);
+ QPainter painter(this);
+ if (!d->pixmap.isNull())
+ painter.drawPixmap(QPoint(), d->pixmap);
+ drawContents(&painter);
+ }
return QWidget::event(e);
}
diff --git a/src/gui/widgets/qstackedwidget.cpp b/src/gui/widgets/qstackedwidget.cpp
index de8d3e6b16..57b43b5972 100644
--- a/src/gui/widgets/qstackedwidget.cpp
+++ b/src/gui/widgets/qstackedwidget.cpp
@@ -49,12 +49,54 @@
QT_BEGIN_NAMESPACE
+/**
+ QStackedLayout does not support height for width (simply because it does not reimplement
+ heightForWidth() and hasHeightForWidth()). That is not possible to fix without breaking
+ binary compatibility. (QLayout is subject to multiple inheritance).
+ However, we can fix QStackedWidget by simply using a modified version of QStackedLayout
+ that reimplements the hfw-related functions:
+ */
+class QStackedLayoutHFW : public QStackedLayout
+{
+public:
+ QStackedLayoutHFW(QWidget *parent = 0) : QStackedLayout(parent) {}
+ bool hasHeightForWidth() const;
+ int heightForWidth(int width) const;
+};
+
+bool QStackedLayoutHFW::hasHeightForWidth() const
+{
+ const int n = count();
+
+ for (int i = 0; i < n; ++i) {
+ if (QLayoutItem *item = itemAt(i)) {
+ if (item->hasHeightForWidth())
+ return true;
+ }
+ }
+ return false;
+}
+
+int QStackedLayoutHFW::heightForWidth(int width) const
+{
+ const int n = count();
+
+ int hfw = 0;
+ for (int i = 0; i < n; ++i) {
+ if (QLayoutItem *item = itemAt(i)) {
+ hfw = qMax(hfw, item->heightForWidth(width));
+ }
+ }
+ return hfw;
+}
+
+
class QStackedWidgetPrivate : public QFramePrivate
{
Q_DECLARE_PUBLIC(QStackedWidget)
public:
QStackedWidgetPrivate():layout(0){}
- QStackedLayout *layout;
+ QStackedLayoutHFW *layout;
bool blockChildAdd;
};
@@ -138,7 +180,7 @@ QStackedWidget::QStackedWidget(QWidget *parent)
: QFrame(*new QStackedWidgetPrivate, parent)
{
Q_D(QStackedWidget);
- d->layout = new QStackedLayout(this);
+ d->layout = new QStackedLayoutHFW(this);
connect(d->layout, SIGNAL(widgetRemoved(int)), this, SIGNAL(widgetRemoved(int)));
connect(d->layout, SIGNAL(currentChanged(int)), this, SIGNAL(currentChanged(int)));
}
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index bbc7e5dd67..8a470ee259 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -1292,6 +1292,8 @@ QSize QTabBar::sizeHint() const
QSize QTabBar::minimumSizeHint() const
{
Q_D(const QTabBar);
+ if (d->layoutDirty)
+ const_cast<QTabBarPrivate*>(d)->layoutTabs();
if (!d->useScrollButtons) {
QRect r;
for (int i = 0; i < d->tabList.count(); ++i)
@@ -1304,22 +1306,23 @@ QSize QTabBar::minimumSizeHint() const
return QSize(d->rightB->sizeHint().width() * 2 + 75, sizeHint().height());
}
+// Compute the most-elided possible text, for minimumSizeHint
static QString computeElidedText(Qt::TextElideMode mode, const QString &text)
{
- if (text.length() <= 7)
+ if (text.length() <= 3)
return text;
static const QLatin1String Ellipses("...");
QString ret;
switch (mode) {
case Qt::ElideRight:
- ret = text.left(4) + Ellipses;
+ ret = text.left(2) + Ellipses;
break;
case Qt::ElideMiddle:
- ret = text.left(2) + Ellipses + text.right(2);
+ ret = text.left(1) + Ellipses + text.right(1);
break;
case Qt::ElideLeft:
- ret = Ellipses + text.right(4);
+ ret = Ellipses + text.right(2);
break;
case Qt::ElideNone:
ret = text;
@@ -1966,7 +1969,7 @@ void QTabBar::keyPressEvent(QKeyEvent *event)
event->ignore();
return;
}
- int offset = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
+ int offset = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
d->setCurrentNextEnabledIndex(offset);
}
diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp
index 4a61935e35..82dfdef7d9 100644
--- a/src/gui/widgets/qtabwidget.cpp
+++ b/src/gui/widgets/qtabwidget.cpp
@@ -195,6 +195,7 @@ public:
void _q_removeTab(int);
void _q_tabMoved(int from, int to);
void init();
+ bool hasHeightForWidth() const;
QTabBar *tabs;
QStackedWidget *stack;
@@ -246,6 +247,15 @@ void QTabWidgetPrivate::init()
}
+bool QTabWidgetPrivate::hasHeightForWidth() const
+{
+ bool has = size_policy.hasHeightForWidth();
+ if (!has && stack)
+ has = qt_widget_private(stack)->hasHeightForWidth();
+ return has;
+}
+
+
/*!
Initialize \a option with the values from this QTabWidget. This method is useful
for subclasses when they need a QStyleOptionTabWidgetFrame, but don't want to fill
@@ -816,8 +826,8 @@ QSize QTabWidget::sizeHint() const
{
Q_D(const QTabWidget);
QSize lc(0, 0), rc(0, 0);
- QStyleOption opt(0);
- opt.init(this);
+ QStyleOptionTabWidgetFrameV2 opt;
+ initStyleOption(&opt);
opt.state = QStyle::State_None;
if (d->leftCornerWidget)
@@ -865,14 +875,58 @@ QSize QTabWidget::minimumSizeHint() const
QSize sz = basicSize(d->pos == North || d->pos == South, lc, rc, s, t);
- QStyleOption opt(0);
- opt.rect = rect();
+ QStyleOptionTabWidgetFrameV2 opt;
+ initStyleOption(&opt);
opt.palette = palette();
opt.state = QStyle::State_None;
return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this)
.expandedTo(QApplication::globalStrut());
}
+/*
+ \reimp
+*/
+int QTabWidget::heightForWidth(int width) const
+{
+ Q_D(const QTabWidget);
+ QStyleOptionTabWidgetFrameV2 opt;
+ initStyleOption(&opt);
+ opt.state = QStyle::State_None;
+
+ QSize zero(0,0);
+ const QSize padding = style()->sizeFromContents(QStyle::CT_TabWidget, &opt, zero, this)
+ .expandedTo(QApplication::globalStrut());
+
+ QSize lc(0, 0), rc(0, 0);
+ if (d->leftCornerWidget)
+ lc = d->leftCornerWidget->sizeHint();
+ if(d->rightCornerWidget)
+ rc = d->rightCornerWidget->sizeHint();
+ if (!d->dirty) {
+ QTabWidget *that = (QTabWidget*)this;
+ that->setUpLayout(true);
+ }
+ QSize t(d->tabs->sizeHint());
+
+ if(usesScrollButtons())
+ t = t.boundedTo(QSize(200,200));
+ else
+ t = t.boundedTo(QApplication::desktop()->size());
+
+ const bool tabIsHorizontal = (d->pos == North || d->pos == South);
+ const int contentsWidth = width - padding.width();
+ int stackWidth = contentsWidth;
+ if (!tabIsHorizontal)
+ stackWidth -= qMax(t.width(), qMax(lc.width(), rc.width()));
+
+ int stackHeight = d->stack->heightForWidth(stackWidth);
+ QSize s(stackWidth, stackHeight);
+
+ QSize contentSize = basicSize(tabIsHorizontal, lc, rc, s, t);
+ return (contentSize + padding).expandedTo(QApplication::globalStrut()).height();
+}
+
+
/*!
\reimp
*/
diff --git a/src/gui/widgets/qtabwidget.h b/src/gui/widgets/qtabwidget.h
index 68200c8c8a..ee5065530a 100644
--- a/src/gui/widgets/qtabwidget.h
+++ b/src/gui/widgets/qtabwidget.h
@@ -129,6 +129,7 @@ public:
QSize sizeHint() const;
QSize minimumSizeHint() const;
+ int heightForWidth(int width) const;
void setCornerWidget(QWidget * w, Qt::Corner corner = Qt::TopRightCorner);
QWidget * cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
diff --git a/src/gui/widgets/qtoolbutton.cpp b/src/gui/widgets/qtoolbutton.cpp
index 1822db8a27..c18f660a43 100644
--- a/src/gui/widgets/qtoolbutton.cpp
+++ b/src/gui/widgets/qtoolbutton.cpp
@@ -394,9 +394,6 @@ void QToolButton::initStyleOption(QStyleOptionToolButton *option) const
option->toolButtonStyle = Qt::ToolButtonTextOnly;
else if (option->toolButtonStyle != Qt::ToolButtonTextOnly)
option->toolButtonStyle = Qt::ToolButtonIconOnly;
- } else {
- if (d->text.isEmpty() && option->toolButtonStyle != Qt::ToolButtonIconOnly)
- option->toolButtonStyle = Qt::ToolButtonIconOnly;
}
option->pos = pos();
diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp
index 7180c4dd79..5cf67a582d 100644
--- a/src/gui/widgets/qworkspace.cpp
+++ b/src/gui/widgets/qworkspace.cpp
@@ -2923,7 +2923,7 @@ void QWorkspaceChild::setActive(bool b)
iconw->setActive(act);
update();
- QList<QWidget*> wl = qFindChildren<QWidget*>(childWidget);
+ QList<QWidget*> wl = childWidget->findChildren<QWidget*>();
if (act) {
for (int i = 0; i < wl.size(); ++i) {
QWidget *w = wl.at(i);
diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp
index ecd03e5dc0..19f3b3c1ca 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp
@@ -127,7 +127,7 @@ QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const
}
}
- delete streams;
+ delete[] streams;
}
}
@@ -201,7 +201,7 @@ QList<int> QAudioDeviceInfoInternal::frequencyList()
rc << vr[i].mMaximum;
}
- delete vr;
+ delete[] vr;
}
}
@@ -345,7 +345,7 @@ QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
}
}
- delete audioDevices;
+ delete[] audioDevices;
}
}
diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp
index 3afbdc95f9..3ec40e82e8 100644
--- a/src/multimedia/video/qvideosurfaceformat.cpp
+++ b/src/multimedia/video/qvideosurfaceformat.cpp
@@ -502,11 +502,11 @@ QList<QByteArray> QVideoSurfaceFormat::propertyNames() const
QVariant QVideoSurfaceFormat::property(const char *name) const
{
if (qstrcmp(name, "handleType") == 0) {
- return qVariantFromValue(d->handleType);
+ return QVariant::fromValue(d->handleType);
} else if (qstrcmp(name, "pixelFormat") == 0) {
- return qVariantFromValue(d->pixelFormat);
+ return QVariant::fromValue(d->pixelFormat);
} else if (qstrcmp(name, "handleType") == 0) {
- return qVariantFromValue(d->handleType);
+ return QVariant::fromValue(d->handleType);
} else if (qstrcmp(name, "frameSize") == 0) {
return d->frameSize;
} else if (qstrcmp(name, "frameWidth") == 0) {
@@ -516,15 +516,15 @@ QVariant QVideoSurfaceFormat::property(const char *name) const
} else if (qstrcmp(name, "viewport") == 0) {
return d->viewport;
} else if (qstrcmp(name, "scanLineDirection") == 0) {
- return qVariantFromValue(d->scanLineDirection);
+ return QVariant::fromValue(d->scanLineDirection);
} else if (qstrcmp(name, "frameRate") == 0) {
- return qVariantFromValue(d->frameRate);
+ return QVariant::fromValue(d->frameRate);
} else if (qstrcmp(name, "pixelAspectRatio") == 0) {
- return qVariantFromValue(d->pixelAspectRatio);
+ return QVariant::fromValue(d->pixelAspectRatio);
} else if (qstrcmp(name, "sizeHint") == 0) {
return sizeHint();
} else if (qstrcmp(name, "yCbCrColorSpace") == 0) {
- return qVariantFromValue(d->ycbcrColorSpace);
+ return QVariant::fromValue(d->ycbcrColorSpace);
} else {
int id = 0;
for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {}
@@ -546,7 +546,7 @@ void QVideoSurfaceFormat::setProperty(const char *name, const QVariant &value)
} else if (qstrcmp(name, "pixelFormat") == 0) {
// read only.
} else if (qstrcmp(name, "frameSize") == 0) {
- if (qVariantCanConvert<QSize>(value)) {
+ if (value.canConvert<QSize>()) {
d->frameSize = qvariant_cast<QSize>(value);
d->viewport = QRect(QPoint(0, 0), d->frameSize);
}
@@ -555,21 +555,21 @@ void QVideoSurfaceFormat::setProperty(const char *name, const QVariant &value)
} else if (qstrcmp(name, "frameHeight") == 0) {
// read only.
} else if (qstrcmp(name, "viewport") == 0) {
- if (qVariantCanConvert<QRect>(value))
+ if (value.canConvert<QRect>())
d->viewport = qvariant_cast<QRect>(value);
} else if (qstrcmp(name, "scanLineDirection") == 0) {
- if (qVariantCanConvert<Direction>(value))
+ if (value.canConvert<Direction>())
d->scanLineDirection = qvariant_cast<Direction>(value);
} else if (qstrcmp(name, "frameRate") == 0) {
- if (qVariantCanConvert<qreal>(value))
+ if (value.canConvert<qreal>())
d->frameRate = qvariant_cast<qreal>(value);
} else if (qstrcmp(name, "pixelAspectRatio") == 0) {
- if (qVariantCanConvert<QSize>(value))
+ if (value.canConvert<QSize>())
d->pixelAspectRatio = qvariant_cast<QSize>(value);
} else if (qstrcmp(name, "sizeHint") == 0) {
// read only.
} else if (qstrcmp(name, "yCbCrColorSpace") == 0) {
- if (qVariantCanConvert<YCbCrColorSpace>(value))
+ if (value.canConvert<YCbCrColorSpace>())
d->ycbcrColorSpace = qvariant_cast<YCbCrColorSpace>(value);
} else {
int id = 0;
diff --git a/src/network/access/qfilenetworkreply.cpp b/src/network/access/qfilenetworkreply.cpp
index 4ac9a8cd99..8c0fd17ce2 100644
--- a/src/network/access/qfilenetworkreply.cpp
+++ b/src/network/access/qfilenetworkreply.cpp
@@ -68,10 +68,9 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req
setRequest(req);
setUrl(req.url());
setOperation(op);
+ setFinished(true);
QNetworkReply::open(QIODevice::ReadOnly);
- qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
-
QFileNetworkReplyPrivate *d = (QFileNetworkReplyPrivate*) d_func();
QUrl url = req.url();
@@ -141,12 +140,6 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req
QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}
-
-bool QFileNetworkReplyPrivate::isFinished() const
-{
- return true;
-}
-
void QFileNetworkReply::close()
{
Q_D(QFileNetworkReply);
diff --git a/src/network/access/qfilenetworkreply_p.h b/src/network/access/qfilenetworkreply_p.h
index 710ec9fda7..227c775687 100644
--- a/src/network/access/qfilenetworkreply_p.h
+++ b/src/network/access/qfilenetworkreply_p.h
@@ -92,8 +92,6 @@ public:
qint64 fileSize;
qint64 filePos;
- virtual bool isFinished() const;
-
Q_DECLARE_PUBLIC(QFileNetworkReply)
};
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index ccdbb20f79..2ab28c7178 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -117,6 +117,7 @@ void QHttpNetworkConnectionPrivate::init()
{
for (int i = 0; i < channelCount; i++) {
channels[i].setConnection(this->q_func());
+ channels[i].ssl = encrypt;
channels[i].init();
}
}
@@ -530,33 +531,35 @@ void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket)
|| channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
return;
-
- //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing highPriorityQueue, size=" << highPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
int lengthBefore;
while (!highPriorityQueue.isEmpty()) {
lengthBefore = channels[i].alreadyPipelinedRequests.length();
fillPipeline(highPriorityQueue, channels[i]);
- if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
+ if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength) {
+ channels[i].pipelineFlush();
return;
+ }
if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
break; // did not process anything, now do the low prio queue
}
- //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing lowPriorityQueue, size=" << lowPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
while (!lowPriorityQueue.isEmpty()) {
lengthBefore = channels[i].alreadyPipelinedRequests.length();
fillPipeline(lowPriorityQueue, channels[i]);
- if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
+ if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength) {
+ channels[i].pipelineFlush();
return;
+ }
if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
break; // did not process anything
}
+ channels[i].pipelineFlush();
}
// returns true when the processing of a queue has been done
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 6437f6fb8f..e39f9ed3ea 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
: socket(0)
+ , ssl(false)
, state(IdleState)
, reply(0)
, written(0)
@@ -90,11 +91,8 @@ void QHttpNetworkConnectionChannel::init()
#else
socket = new QTcpSocket;
#endif
-
- // limit the socket read buffer size. we will read everything into
- // the QHttpNetworkReply anyway, so let's grow only that and not
- // here and there.
- socket->setReadBufferSize(64*1024);
+ // Set by QNAM anyway, but let's be safe here
+ socket->setProxy(QNetworkProxy::NoProxy);
QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
this, SLOT(_q_bytesWritten(qint64)),
@@ -164,11 +162,12 @@ bool QHttpNetworkConnectionChannel::sendRequest()
written = 0; // excluding the header
bytesTotal = 0;
- reply->d_func()->clear();
- reply->d_func()->connection = connection;
- reply->d_func()->connectionChannel = this;
- reply->d_func()->autoDecompress = request.d->autoDecompress;
- reply->d_func()->pipeliningUsed = false;
+ QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
+ replyPrivate->clear();
+ replyPrivate->connection = connection;
+ replyPrivate->connectionChannel = this;
+ replyPrivate->autoDecompress = request.d->autoDecompress;
+ replyPrivate->pipeliningUsed = false;
pendingEncrypt = false;
// if the url contains authentication parameters, use the new ones
@@ -328,7 +327,6 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
return;
}
- qint64 bytes = 0;
QAbstractSocket::SocketState socketState = socket->state();
// connection might be closed to signal the end of data
@@ -349,12 +347,14 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
}
// read loop for the response
- while (socket->bytesAvailable()) {
+ qint64 bytes = 0;
+ qint64 lastBytes = bytes;
+ do {
+ lastBytes = bytes;
+
QHttpNetworkReplyPrivate::ReplyState state = reply->d_func()->state;
switch (state) {
case QHttpNetworkReplyPrivate::NothingDoneState: {
- // only eat whitespace on the first call
- eatWhitespace();
state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
// fallthrough
}
@@ -378,6 +378,7 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
return;
}
bytes += headerBytes;
+ // If headers were parsed successfully now it is the ReadingDataState
if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
if (replyPrivate->isGzipped() && replyPrivate->autoDecompress) {
// remove the Content-Length from header
@@ -392,6 +393,10 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
}
if (replyPrivate->shouldEmitSignals())
emit reply->headerChanged();
+ // After headerChanged had been emitted
+ // we can suddenly have a replyPrivate->userProvidedDownloadBuffer
+ // this is handled in the ReadingDataState however
+
if (!replyPrivate->expectContent()) {
replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState;
allDone();
@@ -412,22 +417,27 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
return;
}
- if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
- && replyPrivate->bodyLength > 0) {
- // bulk files like images should fulfill these properties and
- // we can therefore save on memory copying
- bytes = replyPrivate->readBodyFast(socket, &replyPrivate->responseData);
- replyPrivate->totalProgress += bytes;
+ if (replyPrivate->userProvidedDownloadBuffer) {
+ // the user provided a direct buffer where we should put all our data in.
+ // this only works when we can tell the user the content length and he/she can allocate
+ // the buffer in that size.
+ // note that this call will read only from the still buffered data
+ qint64 haveRead = replyPrivate->readBodyVeryFast(socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress);
+ bytes += haveRead;
+ replyPrivate->totalProgress += haveRead;
+
+ // the user will get notified of it via progress signal
+ emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
+ } else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
+ && replyPrivate->bodyLength > 0) {
+ // bulk files like images should fulfill these properties and
+ // we can therefore save on memory copying
+ qint64 haveRead = replyPrivate->readBodyFast(socket, &replyPrivate->responseData);
+ bytes += haveRead;
+ replyPrivate->totalProgress += haveRead;
if (replyPrivate->shouldEmitSignals()) {
- QPointer<QHttpNetworkReply> replyPointer = reply;
emit reply->readyRead();
- // make sure that the reply is valid
- if (replyPointer.isNull())
- return;
emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
- // make sure that the reply is valid
- if (replyPointer.isNull())
- return;
}
}
else
@@ -435,8 +445,9 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
// use the traditional slower reading (for compressed encoding, chunked encoding,
// no content-length etc)
QByteDataBuffer byteDatas;
- bytes = replyPrivate->readBody(socket, &byteDatas);
- if (bytes) {
+ qint64 haveRead = replyPrivate->readBody(socket, &byteDatas);
+ if (haveRead) {
+ bytes += haveRead;
if (replyPrivate->autoDecompress)
replyPrivate->appendCompressedReplyData(byteDatas);
else
@@ -445,17 +456,10 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
if (!replyPrivate->autoDecompress) {
replyPrivate->totalProgress += bytes;
if (replyPrivate->shouldEmitSignals()) {
- QPointer<QHttpNetworkReply> replyPointer = reply;
// important: At the point of this readyRead(), the byteDatas list must be empty,
// else implicit sharing will trigger memcpy when the user is reading data!
emit reply->readyRead();
- // make sure that the reply is valid
- if (replyPointer.isNull())
- return;
emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
- // make sure that the reply is valid
- if (replyPointer.isNull())
- return;
}
}
#ifndef QT_NO_COMPRESS
@@ -477,7 +481,7 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
default:
break;
}
- }
+ } while (bytes != lastBytes && reply);
}
// called when unexpectedly reading a -1 or when data is expected but socket is closed
@@ -520,7 +524,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
if (socketState != QAbstractSocket::ConnectedState) {
// connect to the host if not already connected.
state = QHttpNetworkConnectionChannel::ConnectingState;
- pendingEncrypt = connection->d_func()->encrypt;
+ pendingEncrypt = ssl;
// reset state
pipeliningSupported = PipeliningSupportUnknown;
@@ -543,23 +547,43 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
#ifndef QT_NO_NETWORKPROXY
// HTTPS always use transparent proxy.
- if (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy && !connection->d_func()->encrypt) {
+ if (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy && !ssl) {
connectHost = connection->d_func()->networkProxy.hostName();
connectPort = connection->d_func()->networkProxy.port();
}
#endif
- if (connection->d_func()->encrypt) {
+ if (ssl) {
#ifndef QT_NO_OPENSSL
QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
sslSocket->connectToHostEncrypted(connectHost, connectPort);
if (ignoreAllSslErrors)
sslSocket->ignoreSslErrors();
sslSocket->ignoreSslErrors(ignoreSslErrorsList);
+
+ // limit the socket read buffer size. we will read everything into
+ // the QHttpNetworkReply anyway, so let's grow only that and not
+ // here and there.
+ socket->setReadBufferSize(64*1024);
#else
connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
#endif
} else {
- socket->connectToHost(connectHost, connectPort);
+ // In case of no proxy we can use the Unbuffered QTcpSocket
+ if (connection->d_func()->networkProxy.type() == QNetworkProxy::NoProxy
+ && connection->cacheProxy().type() == QNetworkProxy::NoProxy
+ && connection->transparentProxy().type() == QNetworkProxy::NoProxy) {
+ socket->connectToHost(connectHost, connectPort, QIODevice::ReadWrite | QIODevice::Unbuffered);
+ // For an Unbuffered QTcpSocket, the read buffer size has a special meaning.
+ socket->setReadBufferSize(1*1024);
+
+ } else {
+ socket->connectToHost(connectHost, connectPort);
+
+ // limit the socket read buffer size. we will read everything into
+ // the QHttpNetworkReply anyway, so let's grow only that and not
+ // here and there.
+ socket->setReadBufferSize(64*1024);
+ }
}
return false;
}
@@ -589,18 +613,10 @@ bool QHttpNetworkConnectionChannel::expand(bool dataComplete)
reply->d_func()->totalProgress += inflated.size();
reply->d_func()->appendUncompressedReplyData(inflated);
if (reply->d_func()->shouldEmitSignals()) {
- QPointer<QHttpNetworkReply> replyPointer = reply;
// important: At the point of this readyRead(), inflated must be cleared,
// else implicit sharing will trigger memcpy when the user is reading data!
emit reply->readyRead();
- // make sure that the reply is valid
- if (replyPointer.isNull())
- return true;
emit reply->dataReadProgress(reply->d_func()->totalProgress, 0);
- // make sure that the reply is valid
- if (replyPointer.isNull())
- return true;
-
}
}
} else {
@@ -678,10 +694,15 @@ void QHttpNetworkConnectionChannel::allDone()
// this was wrong, allDone gets called from that function anyway.
}
} else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) {
- eatWhitespace();
// this is weird. we had nothing pipelined but still bytes available. better close it.
- if (socket->bytesAvailable() > 0)
- close();
+ //if (socket->bytesAvailable() > 0)
+ // close();
+ //
+ // FIXME
+ // We do not close it anymore now, but should introduce this again after having fixed
+ // the chunked decoder in QHttpNetworkReply to read the whitespace after the last chunk.
+ // (Currently this is worked around by readStatus in the QHttpNetworkReply ignoring
+ // leading whitespace.
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
} else if (alreadyPipelinedRequests.isEmpty()) {
if (qobject_cast<QHttpNetworkConnection*>(connection))
@@ -728,30 +749,6 @@ void QHttpNetworkConnectionChannel::requeueCurrentlyPipelinedRequests()
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
-void QHttpNetworkConnectionChannel::eatWhitespace()
-{
- char c;
- do {
- qint64 ret = socket->peek(&c, 1);
-
- // nothing read, fine.
- if (ret == 0)
- return;
-
- // EOF from socket?
- if (ret == -1)
- return; // FIXME, we need to stop processing. however the next stuff done will also do that.
-
- // read all whitespace and line endings
- if (c == 11 || c == '\n' || c == '\r' || c == ' ' || c == 31) {
- socket->read(&c, 1);
- continue;
- } else {
- break;
- }
- } while(true);
-}
-
void QHttpNetworkConnectionChannel::handleStatus()
{
Q_ASSERT(socket);
@@ -813,7 +810,7 @@ bool QHttpNetworkConnectionChannel::resetUploadData()
}
-void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair)
+void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair)
{
// this is only called for simple GET
@@ -826,16 +823,32 @@ void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair)
reply->d_func()->pipeliningUsed = true;
#ifndef QT_NO_NETWORKPROXY
- QByteArray header = QHttpNetworkRequestPrivate::header(request,
- (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy));
+ pipeline.append(QHttpNetworkRequestPrivate::header(request,
+ (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy)));
#else
- QByteArray header = QHttpNetworkRequestPrivate::header(request, false);
+ pipeline.append(QHttpNetworkRequestPrivate::header(request, false));
#endif
- socket->write(header);
alreadyPipelinedRequests.append(pair);
+
+ // pipelineFlush() needs to be called at some point afterwards
}
+void QHttpNetworkConnectionChannel::pipelineFlush()
+{
+ if (pipeline.isEmpty())
+ return;
+
+ // The goal of this is so that we have everything in one TCP packet.
+ // For the Unbuffered QTcpSocket this is manually needed, the buffered
+ // QTcpSocket does it automatically.
+ // Also, sometimes the OS does it for us (Nagle's algorithm) but that
+ // happens only sometimes.
+ socket->write(pipeline);
+ pipeline.clear();
+}
+
+
void QHttpNetworkConnectionChannel::closeAndResendCurrentRequest()
{
requeueCurrentlyPipelinedRequests();
@@ -868,6 +881,19 @@ bool QHttpNetworkConnectionChannel::isSocketReading() const
//private slots
void QHttpNetworkConnectionChannel::_q_readyRead()
{
+ // We got a readyRead but no bytes are available..
+ // This happens for the Unbuffered QTcpSocket
+ // Also check if socket is in ConnectedState since
+ // this function may also be invoked via the event loop.
+ if (socket->state() == QAbstractSocket::ConnectedState && socket->bytesAvailable() == 0) {
+ char c;
+ qint64 ret = socket->peek(&c, 1);
+ if (ret < 0) {
+ socket->disconnectFromHost();
+ return;
+ }
+ }
+
if (isSocketWaiting() || isSocketReading()) {
state = QHttpNetworkConnectionChannel::ReadingState;
if (reply)
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 41a896dc86..4f3a65c3eb 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -99,6 +99,7 @@ public:
BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState)
};
QAbstractSocket *socket;
+ bool ssl;
ChannelState state;
QHttpNetworkRequest request; // current request
QHttpNetworkReply *reply; // current reply for this request
@@ -125,7 +126,11 @@ public:
};
PipeliningSupport pipeliningSupported;
QList<HttpMessagePair> alreadyPipelinedRequests;
-
+ QByteArray pipeline; // temporary buffer that gets sent to socket in pipelineFlush
+ void pipelineInto(HttpMessagePair &pair);
+ void pipelineFlush();
+ void requeueCurrentlyPipelinedRequests();
+ void detectPipeliningSupport();
QHttpNetworkConnectionChannel();
@@ -145,15 +150,9 @@ public:
bool resetUploadData(); // return true if resetting worked or there is no upload data
- void pipelineInto(HttpMessagePair &pair);
- void requeueCurrentlyPipelinedRequests();
- void detectPipeliningSupport();
-
void handleUnexpectedEOF();
void closeAndResendCurrentRequest();
- void eatWhitespace();
-
bool isSocketBusy() const;
bool isSocketWriting() const;
bool isSocketWaiting() const;
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 108ba8a369..1c55482875 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -119,6 +119,7 @@ void QHttpNetworkReply::setRequest(const QHttpNetworkRequest &request)
{
Q_D(QHttpNetworkReply);
d->request = request;
+ d->ssl = request.isSsl();
}
int QHttpNetworkReply::statusCode() const
@@ -195,6 +196,25 @@ void QHttpNetworkReply::setDownstreamLimited(bool dsl)
d->connection->d_func()->readMoreLater(this);
}
+bool QHttpNetworkReply::supportsUserProvidedDownloadBuffer()
+{
+ Q_D(QHttpNetworkReply);
+ return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0);
+}
+
+void QHttpNetworkReply::setUserProvidedDownloadBuffer(char* b)
+{
+ Q_D(QHttpNetworkReply);
+ if (supportsUserProvidedDownloadBuffer())
+ d->userProvidedDownloadBuffer = b;
+}
+
+char* QHttpNetworkReply::userProvidedDownloadBuffer()
+{
+ Q_D(QHttpNetworkReply);
+ return d->userProvidedDownloadBuffer;
+}
+
bool QHttpNetworkReply::isFinished() const
{
return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState;
@@ -207,7 +227,10 @@ bool QHttpNetworkReply::isPipeliningUsed() const
QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
- : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100),
+ : QHttpNetworkHeaderPrivate(newUrl)
+ , state(NothingDoneState)
+ , ssl(false)
+ , statusCode(100),
majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0),
chunkedTransferEncoding(false),
connectionCloseEnabled(true),
@@ -215,6 +238,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false),
autoDecompress(false), responseData(), requestIsPrepared(false)
,pipeliningUsed(false), downstreamLimited(false)
+ ,userProvidedDownloadBuffer(0)
{
}
@@ -448,6 +472,8 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
return -1; // unexpected EOF
else if (haveRead == 0)
break; // read more later
+ else if (haveRead == 1 && bytes == 0 && (c == 11 || c == '\n' || c == '\r' || c == ' ' || c == 31))
+ continue; // Ignore all whitespace that was trailing froma previous request on that socket
bytes++;
@@ -623,12 +649,32 @@ bool QHttpNetworkReplyPrivate::isConnectionCloseEnabled()
// note this function can only be used for non-chunked, non-compressed with
// known content length
+qint64 QHttpNetworkReplyPrivate::readBodyVeryFast(QAbstractSocket *socket, char *b)
+{
+ // This first read is to flush the buffer inside the socket
+ qint64 haveRead = 0;
+ haveRead = socket->read(b, bodyLength - contentRead);
+ if (haveRead == -1) {
+ return 0; // ### error checking here;
+ }
+ contentRead += haveRead;
+
+ if (contentRead == bodyLength) {
+ state = AllDoneState;
+ }
+
+ return haveRead;
+}
+
+// note this function can only be used for non-chunked, non-compressed with
+// known content length
qint64 QHttpNetworkReplyPrivate::readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb)
{
+
qint64 toBeRead = qMin(socket->bytesAvailable(), bodyLength - contentRead);
QByteArray bd;
bd.resize(toBeRead);
- qint64 haveRead = socket->read(bd.data(), bd.size());
+ qint64 haveRead = socket->read(bd.data(), toBeRead);
if (haveRead == -1) {
bd.clear();
return 0; // ### error checking here;
@@ -650,29 +696,34 @@ qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QByteDataBuff
{
qint64 bytes = 0;
if (isChunked()) {
- bytes += readReplyBodyChunked(socket, out); // chunked transfer encoding (rfc 2616, sec 3.6)
- } else if (bodyLength > 0) { // we have a Content-Length
+ // chunked transfer encoding (rfc 2616, sec 3.6)
+ bytes += readReplyBodyChunked(socket, out);
+ } else if (bodyLength > 0) {
+ // we have a Content-Length
bytes += readReplyBodyRaw(socket, out, bodyLength - contentRead);
if (contentRead + bytes == bodyLength)
state = AllDoneState;
} else {
+ // no content length. just read what's possible
bytes += readReplyBodyRaw(socket, out, socket->bytesAvailable());
}
contentRead += bytes;
return bytes;
}
-qint64 QHttpNetworkReplyPrivate::readReplyBodyRaw(QIODevice *in, QByteDataBuffer *out, qint64 size)
+qint64 QHttpNetworkReplyPrivate::readReplyBodyRaw(QAbstractSocket *socket, QByteDataBuffer *out, qint64 size)
{
+ // FIXME get rid of this function and just use readBodyFast and give it socket->bytesAvailable()
qint64 bytes = 0;
- Q_ASSERT(in);
+ Q_ASSERT(socket);
Q_ASSERT(out);
- int toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, in->bytesAvailable()));
+ int toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, socket->bytesAvailable()));
+
while (toBeRead > 0) {
QByteArray byteData;
byteData.resize(toBeRead);
- qint64 haveRead = in->read(byteData.data(), byteData.size());
+ qint64 haveRead = socket->read(byteData.data(), byteData.size());
if (haveRead <= 0) {
// ### error checking here
byteData.clear();
@@ -684,25 +735,35 @@ qint64 QHttpNetworkReplyPrivate::readReplyBodyRaw(QIODevice *in, QByteDataBuffer
bytes += haveRead;
size -= haveRead;
- toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, in->bytesAvailable()));
+ toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, socket->bytesAvailable()));
}
return bytes;
}
-qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QIODevice *in, QByteDataBuffer *out)
+qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, QByteDataBuffer *out)
{
qint64 bytes = 0;
- while (in->bytesAvailable()) { // while we can read from input
- // if we are done with the current chunk, get the size of the new chunk
+ while (socket->bytesAvailable()) {
if (currentChunkRead >= currentChunkSize) {
+ // For the first chunk and when we're done with a chunk
currentChunkSize = 0;
currentChunkRead = 0;
if (bytes) {
+ // After a chunk
char crlf[2];
- bytes += in->read(crlf, 2); // read the "\r\n" after the chunk
+ // read the "\r\n" after the chunk
+ qint64 haveRead = socket->read(crlf, 2);
+ // FIXME: This code is slightly broken and not optimal. What if the 2 bytes are not available yet?!
+ // For nice reasons (the toLong in getChunkSize accepting \n at the beginning
+ // it right now still works, but we should definitely fix this.
+
+ if (haveRead != 2)
+ return bytes; // FIXME
+ bytes += haveRead;
}
- bytes += getChunkSize(in, &currentChunkSize);
+ // Note that chunk size gets stored in currentChunkSize, what is returned is the bytes read
+ bytes += getChunkSize(socket, &currentChunkSize);
if (currentChunkSize == -1)
break;
}
@@ -712,8 +773,8 @@ qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QIODevice *in, QByteDataBu
break;
}
- // otherwise, try to read what is missing for this chunk
- qint64 haveRead = readReplyBodyRaw (in, out, currentChunkSize - currentChunkRead);
+ // otherwise, try to begin reading this chunk / to read what is missing for this chunk
+ qint64 haveRead = readReplyBodyRaw (socket, out, currentChunkSize - currentChunkRead);
currentChunkRead += haveRead;
bytes += haveRead;
@@ -723,22 +784,25 @@ qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QIODevice *in, QByteDataBu
return bytes;
}
-qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize)
+qint64 QHttpNetworkReplyPrivate::getChunkSize(QAbstractSocket *socket, qint64 *chunkSize)
{
qint64 bytes = 0;
char crlf[2];
*chunkSize = -1;
- int bytesAvailable = in->bytesAvailable();
+
+ int bytesAvailable = socket->bytesAvailable();
+ // FIXME rewrite to permanent loop without bytesAvailable
while (bytesAvailable > bytes) {
- qint64 sniffedBytes = in->peek(crlf, 2);
+ qint64 sniffedBytes = socket->peek(crlf, 2);
int fragmentSize = fragment.size();
+
// check the next two bytes for a "\r\n", skip blank lines
if ((fragmentSize && sniffedBytes == 2 && crlf[0] == '\r' && crlf[1] == '\n')
||(fragmentSize > 1 && fragment.endsWith('\r') && crlf[0] == '\n'))
{
- bytes += in->read(crlf, 1); // read the \r or \n
+ bytes += socket->read(crlf, 1); // read the \r or \n
if (crlf[0] == '\r')
- bytes += in->read(crlf, 1); // read the \n
+ bytes += socket->read(crlf, 1); // read the \n
bool ok = false;
// ignore the chunk-extension
fragment = fragment.mid(0, fragment.indexOf(';')).trimmed();
@@ -748,10 +812,15 @@ qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize)
} else {
// read the fragment to the buffer
char c = 0;
- bytes += in->read(&c, 1);
+ qint64 haveRead = socket->read(&c, 1);
+ if (haveRead < 0) {
+ return -1; // FIXME
+ }
+ bytes += haveRead;
fragment.append(c);
}
}
+
return bytes;
}
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 4011c78f7f..02ce248cde 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -128,6 +128,10 @@ public:
QByteArray readAny();
void setDownstreamLimited(bool t);
+ bool supportsUserProvidedDownloadBuffer();
+ void setUserProvidedDownloadBuffer(char*);
+ char* userProvidedDownloadBuffer();
+
bool isFinished() const;
bool isPipeliningUsed() const;
@@ -147,6 +151,7 @@ Q_SIGNALS:
void finished();
void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
void headerChanged();
+ // FIXME we need to change this to qint64!
void dataReadProgress(int done, int total);
void dataSendProgress(qint64 done, qint64 total);
@@ -168,15 +173,16 @@ public:
qint64 readHeader(QAbstractSocket *socket);
void parseHeader(const QByteArray &header);
qint64 readBody(QAbstractSocket *socket, QByteDataBuffer *out);
+ qint64 readBodyVeryFast(QAbstractSocket *socket, char *b);
qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb);
bool findChallenge(bool forProxy, QByteArray &challenge) const;
QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
void clear();
void clearHttpLayerInformation();
- qint64 readReplyBodyRaw(QIODevice *in, QByteDataBuffer *out, qint64 size);
- qint64 readReplyBodyChunked(QIODevice *in, QByteDataBuffer *out);
- qint64 getChunkSize(QIODevice *in, qint64 *chunkSize);
+ qint64 readReplyBodyRaw(QAbstractSocket *in, QByteDataBuffer *out, qint64 size);
+ qint64 readReplyBodyChunked(QAbstractSocket *in, QByteDataBuffer *out);
+ qint64 getChunkSize(QAbstractSocket *in, qint64 *chunkSize);
void appendUncompressedReplyData(QByteArray &qba);
void appendUncompressedReplyData(QByteDataBuffer &data);
@@ -205,6 +211,7 @@ public:
} state;
QHttpNetworkRequest request;
+ bool ssl;
int statusCode;
int majorVersion;
int minorVersion;
@@ -234,6 +241,8 @@ public:
bool pipeliningUsed;
bool downstreamLimited;
+
+ char* userProvidedDownloadBuffer;
};
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 639025e7ff..d2f3212378 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -63,6 +63,7 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest
pipeliningAllowed = other.pipeliningAllowed;
customVerb = other.customVerb;
withCredentials = other.withCredentials;
+ ssl = other.ssl;
}
QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate()
@@ -73,6 +74,7 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
{
return QHttpNetworkHeaderPrivate::operator==(other)
&& (operation == other.operation)
+ && (ssl == other.ssl)
&& (uploadByteDevice == other.uploadByteDevice);
}
@@ -199,6 +201,15 @@ void QHttpNetworkRequest::setUrl(const QUrl &url)
d->url = url;
}
+bool QHttpNetworkRequest::isSsl() const
+{
+ return d->ssl;
+}
+void QHttpNetworkRequest::setSsl(bool s)
+{
+ d->ssl = s;
+}
+
qint64 QHttpNetworkRequest::contentLength() const
{
return d->contentLength();
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index 15cab73e8f..123babcefe 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -116,6 +116,9 @@ public:
bool withCredentials() const;
void setWithCredentials(bool b);
+ bool isSsl() const;
+ void setSsl(bool);
+
void setUploadByteDevice(QNonContiguousByteDevice *bd);
QNonContiguousByteDevice* uploadByteDevice() const;
@@ -146,6 +149,7 @@ public:
bool autoDecompress;
bool pipeliningAllowed;
bool withCredentials;
+ bool ssl;
};
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 60f7dc6369..c3d765b750 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -146,7 +146,7 @@ QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
// and the special backends need to access this.
void QNetworkAccessBackend::emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal)
{
- if (reply->isFinished())
+ if (reply->isFinished)
return;
reply->emitUploadProgress(bytesSent, bytesTotal);
}
@@ -252,6 +252,17 @@ void QNetworkAccessBackend::writeDownstreamData(QIODevice *data)
reply->appendDownstreamData(data);
}
+// not actually appending data, it was already written to the user buffer
+void QNetworkAccessBackend::writeDownstreamDataDownloadBuffer(qint64 bytesReceived, qint64 bytesTotal)
+{
+ reply->appendDownstreamDataDownloadBuffer(bytesReceived, bytesTotal);
+}
+
+char* QNetworkAccessBackend::getDownloadBuffer(qint64 size)
+{
+ return reply->getDownloadBuffer(size);
+}
+
QVariant QNetworkAccessBackend::header(QNetworkRequest::KnownHeaders header) const
{
return reply->q_func()->header(header);
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index 4fe6de6669..9f8a01f864 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -177,6 +177,10 @@ protected:
qint64 nextDownstreamBlockSize() const;
void writeDownstreamData(QByteDataBuffer &list);
+ // not actually appending data, it was already written to the user buffer
+ void writeDownstreamDataDownloadBuffer(qint64, qint64);
+ char* getDownloadBuffer(qint64);
+
public slots:
// for task 251801, needs to be a slot to be called asynchronously
void writeDownstreamData(QIODevice *data);
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index 4560153dee..710c258466 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -65,10 +65,15 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
}
QUrl url = request.url();
- if (url.scheme() == QLatin1String("qrc") || !url.toLocalFile().isEmpty())
+ if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0 || url.isLocalFile()) {
return new QNetworkAccessFileBackend;
- else if (!url.isEmpty() && url.authority().isEmpty()) {
- // check if QFile could, in theory, open this URL
+ } else if (!url.scheme().isEmpty() && url.authority().isEmpty()) {
+ // check if QFile could, in theory, open this URL via the file engines
+ // it has to be in the format:
+ // prefix:path/to/file
+ // or prefix:/path/to/file
+ //
+ // this construct here must match the one below in open()
QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery));
if (fi.exists() || (op == QNetworkAccessManager::PutOperation && fi.dir().exists()))
return new QNetworkAccessFileBackend;
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 1a5901129f..da336d0349 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -77,7 +77,7 @@ QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op,
}
QUrl url = request.url();
- if (url.scheme() == QLatin1String("ftp"))
+ if (url.scheme().compare(QLatin1String("ftp"), Qt::CaseInsensitive) == 0)
return new QNetworkAccessFtpBackend;
return 0;
}
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index f617244b17..8b9a99f31c 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -542,6 +542,9 @@ void QNetworkAccessHttpBackend::postRequest()
break; // can't happen
}
+ bool encrypt = (url().scheme().toLower() == QLatin1String("https"));
+ httpRequest.setSsl(encrypt);
+
httpRequest.setUrl(url());
QList<QByteArray> headers = request().rawHeaderList();
@@ -595,7 +598,6 @@ void QNetworkAccessHttpBackend::postRequest()
httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList);
#endif
- connect(httpReply, SIGNAL(readyRead()), SLOT(replyReadyRead()));
connect(httpReply, SIGNAL(finished()), SLOT(replyFinished()));
connect(httpReply, SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
SLOT(httpError(QNetworkReply::NetworkError,QString)));
@@ -859,9 +861,33 @@ void QNetworkAccessHttpBackend::replyHeaderChanged()
if (!isCachingEnabled())
setCachingEnabled(true);
}
+
+ // Check if a download buffer is supported from the HTTP reply
+ char *buf = 0;
+ if (httpReply->supportsUserProvidedDownloadBuffer()) {
+ // Check if a download buffer is supported by the user
+ buf = getDownloadBuffer(httpReply->contentLength());
+ if (buf) {
+ httpReply->setUserProvidedDownloadBuffer(buf);
+ // If there is a download buffer we react on the progress signal
+ connect(httpReply, SIGNAL(dataReadProgress(int,int)), SLOT(replyDownloadProgressSlot(int,int)));
+ }
+ }
+
+ // If there is no buffer, we react on the readyRead signal
+ if (!buf) {
+ connect(httpReply, SIGNAL(readyRead()), SLOT(replyReadyRead()));
+ }
+
metaDataChanged();
}
+void QNetworkAccessHttpBackend::replyDownloadProgressSlot(int received, int total)
+{
+ // we can be sure here that there is a download buffer
+ writeDownstreamDataDownloadBuffer(received, total);
+}
+
void QNetworkAccessHttpBackend::httpAuthenticationRequired(const QHttpNetworkRequest &,
QAuthenticator *auth)
{
@@ -1169,6 +1195,11 @@ bool QNetworkAccessHttpBackend::canResume() const
return false;
}
+ // If we're using a download buffer then we don't support resuming/migration
+ // right now. Too much trouble.
+ if (httpReply->userProvidedDownloadBuffer())
+ return false;
+
return true;
}
diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h
index c4c88ae305..fb127817d5 100644
--- a/src/network/access/qnetworkaccesshttpbackend_p.h
+++ b/src/network/access/qnetworkaccesshttpbackend_p.h
@@ -104,6 +104,7 @@ private slots:
void replyReadyRead();
void replyFinished();
void replyHeaderChanged();
+ void replyDownloadProgressSlot(int,int);
void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
void httpCacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *auth);
void httpError(QNetworkReply::NetworkError error, const QString &errorString);
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index b35c31809c..234305e891 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -450,6 +450,8 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
: QObject(*new QNetworkAccessManagerPrivate, parent)
{
ensureInitialized();
+
+ qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
}
/*!
@@ -944,21 +946,20 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
{
Q_D(QNetworkAccessManager);
+ bool isLocalFile = req.url().isLocalFile();
+
// fast path for GET on file:// URLs
- // Also if the scheme is empty we consider it a file.
// The QNetworkAccessFileBackend will right now only be used
// for PUT or qrc://
if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
- && (req.url().scheme() == QLatin1String("file")
- || req.url().scheme().isEmpty())) {
+ && isLocalFile) {
return new QFileNetworkReply(this, req, op);
}
#ifndef QT_NO_BEARERMANAGEMENT
// Return a disabled network reply if network access is disabled.
// Except if the scheme is empty or file://.
- if (!d->networkAccessible && !(req.url().scheme() == QLatin1String("file") ||
- req.url().scheme().isEmpty())) {
+ if (!d->networkAccessible && !isLocalFile) {
return new QDisabledNetworkReply(this, req, op);
}
@@ -992,7 +993,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
if (d->cookieJar) {
QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url());
if (!cookies.isEmpty())
- request.setHeader(QNetworkRequest::CookieHeader, qVariantFromValue(cookies));
+ request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));
}
}
@@ -1000,7 +1001,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
QUrl url = request.url();
QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
#ifndef QT_NO_BEARERMANAGEMENT
- if (req.url().scheme() != QLatin1String("file") && !req.url().scheme().isEmpty()) {
+ if (!isLocalFile) {
connect(this, SIGNAL(networkSessionConnected()),
reply, SLOT(_q_networkSessionConnected()));
}
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index 261ed20490..f55f67dd50 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -49,6 +49,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
: readBufferMaxSize(0),
operation(QNetworkAccessManager::UnknownOperation),
errorCode(QNetworkReply::NoError)
+ , isFinished(false)
{
// set the default attribute values
attributes.insert(QNetworkRequest::ConnectionEncryptedAttribute, false);
@@ -462,7 +463,7 @@ QNetworkReply::NetworkError QNetworkReply::error() const
*/
bool QNetworkReply::isFinished() const
{
- return d_func()->isFinished();
+ return d_func()->isFinished;
}
/*!
@@ -718,6 +719,21 @@ void QNetworkReply::setError(NetworkError errorCode, const QString &errorString)
}
/*!
+ \since 4.8
+ Sets the reply as \a finished.
+
+ After having this set the replies data must not change.
+
+ \sa isFinished()
+*/
+void QNetworkReply::setFinished(bool finished)
+{
+ Q_D(QNetworkReply);
+ d->isFinished = finished;
+}
+
+
+/*!
Sets the URL being processed to be \a url. Normally, the URL
matches that of the request that was posted, but for a variety of
reasons it can be different (for example, a file path being made
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index acb7379a14..b39fd32c3d 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -163,6 +163,7 @@ protected:
void setOperation(QNetworkAccessManager::Operation operation);
void setRequest(const QNetworkRequest &request);
void setError(NetworkError errorCode, const QString &errorString);
+ void setFinished(bool);
void setUrl(const QUrl &url);
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);
void setRawHeader(const QByteArray &headerName, const QByteArray &value);
diff --git a/src/network/access/qnetworkreply_p.h b/src/network/access/qnetworkreply_p.h
index d7b8ab0d88..2e2e0bc16c 100644
--- a/src/network/access/qnetworkreply_p.h
+++ b/src/network/access/qnetworkreply_p.h
@@ -71,12 +71,11 @@ public:
qint64 readBufferMaxSize;
QNetworkAccessManager::Operation operation;
QNetworkReply::NetworkError errorCode;
+ bool isFinished;
static inline void setManager(QNetworkReply *reply, QNetworkAccessManager *manager)
{ reply->d_func()->manager = manager; }
- virtual bool isFinished() const { return false; }
-
Q_DECLARE_PUBLIC(QNetworkReply)
};
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 5850494805..3a629cf575 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -49,10 +49,16 @@
#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccesshttpbackend_p.h"
#include "qnetworkaccessmanager_p.h"
+#include <QVarLengthArray>
#include <QtCore/QCoreApplication>
QT_BEGIN_NAMESPACE
+typedef QSharedPointer<QVarLengthArray<char, 0> > QVarLengthArraySharedPointer;
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QVarLengthArraySharedPointer)
+
+QT_BEGIN_NAMESPACE
inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
: backend(0), outgoingData(0), outgoingDataBuffer(0),
@@ -62,6 +68,8 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), preMigrationDownloaded(-1),
httpStatusCode(0),
state(Idle)
+ , downloadBuffer(0)
+ , downloadBufferPosition(0)
{
}
@@ -125,6 +133,10 @@ void QNetworkReplyImplPrivate::_q_copyReadyRead()
if (!copyDevice || !q->isOpen())
return;
+ // FIXME Optimize to use download buffer if it is a QBuffer.
+ // Needs to be done where sendCacheContents() (?) of HTTP is emitting
+ // metaDataChanged ?
+
forever {
qint64 bytesToRead = nextDownstreamBlockSize();
if (bytesToRead == 0)
@@ -543,8 +555,6 @@ void QNetworkReplyImplPrivate::appendDownstreamDataSignalEmissions()
{
Q_Q(QNetworkReplyImpl);
- QPointer<QNetworkReplyImpl> qq = q;
-
QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
if (preMigrationDownloaded != Q_INT64_C(-1))
totalSize = totalSize.toLongLong() + preMigrationDownloaded;
@@ -555,13 +565,10 @@ void QNetworkReplyImplPrivate::appendDownstreamDataSignalEmissions()
// else implicit sharing will trigger memcpy when the user is reading data!
emit q->readyRead();
- // hopefully we haven't been deleted here
- if (!qq.isNull()) {
- resumeNotificationHandling();
- // do we still have room in the buffer?
- if (nextDownstreamBlockSize() > 0)
- backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite);
- }
+ resumeNotificationHandling();
+ // do we still have room in the buffer?
+ if (nextDownstreamBlockSize() > 0)
+ backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite);
}
// this is used when it was fetched from the cache, right?
@@ -596,6 +603,55 @@ void QNetworkReplyImplPrivate::appendDownstreamData(const QByteArray &data)
qFatal("QNetworkReplyImplPrivate::appendDownstreamData not implemented");
}
+char* QNetworkReplyImplPrivate::getDownloadBuffer(qint64 size)
+{
+ Q_Q(QNetworkReplyImpl);
+
+ // Check attribute() if allocating a buffer of that size can be allowed
+ if (!downloadBuffer) {
+ QVariant bufferAllocationPolicy = request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute);
+ if (bufferAllocationPolicy.isValid() && bufferAllocationPolicy.toLongLong() >= size) {
+ downloadBufferArray = QSharedPointer<QVarLengthArray<char, 0> >(new QVarLengthArray<char, 0>());
+ downloadBufferArray->reserve(size);
+
+ downloadBuffer = downloadBufferArray->data();
+
+ q->setAttribute(QNetworkRequest::DownloadBufferAttribute, qVariantFromValue<QSharedPointer<QVarLengthArray<char, 0> > > (downloadBufferArray));
+ }
+ }
+
+ return downloadBuffer;
+}
+
+void QNetworkReplyImplPrivate::appendDownstreamDataDownloadBuffer(qint64 bytesReceived, qint64 bytesTotal)
+{
+ Q_Q(QNetworkReplyImpl);
+ if (!q->isOpen())
+ return;
+
+ if (cacheEnabled && !cacheSaveDevice)
+ initCacheSaveDevice();
+
+ if (cacheSaveDevice && bytesReceived == bytesTotal) {
+// if (lastBytesDownloaded == -1)
+// lastBytesDownloaded = 0;
+// cacheSaveDevice->write(downloadBuffer + lastBytesDownloaded, bytesReceived - lastBytesDownloaded);
+
+ // Write everything in one go if we use a download buffer. might be more performant.
+ cacheSaveDevice->write(downloadBuffer, bytesTotal);
+ }
+
+ bytesDownloaded = bytesReceived;
+ lastBytesDownloaded = bytesReceived;
+
+ // Update the array so our user (e.g. QtWebKit) knows the real size
+ if (bytesReceived > 0)
+ downloadBufferArray->resize(bytesReceived);
+
+ emit q->downloadProgress(bytesDownloaded, bytesTotal);
+ emit q->readyRead();
+}
+
void QNetworkReplyImplPrivate::finished()
{
Q_Q(QNetworkReplyImpl);
@@ -634,6 +690,8 @@ void QNetworkReplyImplPrivate::finished()
resumeNotificationHandling();
state = Finished;
+ q->setFinished(true);
+
pendingNotifications.clear();
pauseNotificationHandling();
@@ -704,11 +762,6 @@ void QNetworkReplyImplPrivate::sslErrors(const QList<QSslError> &errors)
#endif
}
-bool QNetworkReplyImplPrivate::isFinished() const
-{
- return (state == Finished || state == Aborted);
-}
-
QNetworkReplyImpl::QNetworkReplyImpl(QObject *parent)
: QNetworkReply(*new QNetworkReplyImplPrivate, parent)
{
@@ -743,7 +796,7 @@ void QNetworkReplyImpl::abort()
QNetworkReply::close();
if (d->state != QNetworkReplyImplPrivate::Finished) {
- // emit signals
+ // call finished which will emit signals
d->error(OperationCanceledError, tr("Operation canceled"));
d->finished();
}
@@ -771,7 +824,7 @@ void QNetworkReplyImpl::close()
QNetworkReply::close();
- // emit signals
+ // call finished which will emit signals
d->error(OperationCanceledError, tr("Operation canceled"));
d->finished();
}
@@ -790,6 +843,13 @@ bool QNetworkReplyImpl::canReadLine () const
*/
qint64 QNetworkReplyImpl::bytesAvailable() const
{
+ // Special case for the "zero copy" download buffer
+ Q_D(const QNetworkReplyImpl);
+ if (d->downloadBuffer) {
+ qint64 maxAvail = d->downloadBufferArray->size() - d->downloadBufferPosition;
+ return QNetworkReply::bytesAvailable() + maxAvail;
+ }
+
return QNetworkReply::bytesAvailable() + d_func()->readBuffer.byteAmount();
}
@@ -844,8 +904,22 @@ void QNetworkReplyImpl::ignoreSslErrorsImplementation(const QList<QSslError> &er
qint64 QNetworkReplyImpl::readData(char *data, qint64 maxlen)
{
Q_D(QNetworkReplyImpl);
+
+ // Special case code if we have the "zero copy" download buffer
+ if (d->downloadBuffer) {
+ qint64 maxAvail = qMin<qint64>(d->downloadBufferArray->size() - d->downloadBufferPosition, maxlen);
+ if (maxAvail == 0)
+ return d->state == QNetworkReplyImplPrivate::Finished ? -1 : 0;
+ // FIXME what about "Aborted" state?
+ qMemCopy(data, d->downloadBuffer + d->downloadBufferPosition, maxAvail);
+ d->downloadBufferPosition += maxAvail;
+ return maxAvail;
+ }
+
+
if (d->readBuffer.isEmpty())
return d->state == QNetworkReplyImplPrivate::Finished ? -1 : 0;
+ // FIXME what about "Aborted" state?
d->backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite);
if (maxlen == 1) {
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 38084bda7c..2cb3082bff 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -62,6 +62,7 @@
#include "QtCore/qbuffer.h"
#include "private/qringbuffer_p.h"
#include "private/qbytedata_p.h"
+#include <QVarLengthArray>
QT_BEGIN_NAMESPACE
@@ -163,14 +164,15 @@ public:
void appendDownstreamData(QIODevice *data);
void appendDownstreamData(const QByteArray &data);
+ char* getDownloadBuffer(qint64 size);
+ void appendDownstreamDataDownloadBuffer(qint64, qint64);
+
void finished();
void error(QNetworkReply::NetworkError code, const QString &errorString);
void metaDataChanged();
void redirectionRequested(const QUrl &target);
void sslErrors(const QList<QSslError> &errors);
- bool isFinished() const;
-
QNetworkAccessBackend *backend;
QIODevice *outgoingData;
QRingBuffer *outgoingDataBuffer;
@@ -191,6 +193,7 @@ public:
QList<QNetworkProxy> proxyList;
#endif
+ // Used for normal downloading. For "zero copy" the downloadBuffer is used
QByteDataBuffer readBuffer;
qint64 bytesDownloaded;
qint64 lastBytesDownloaded;
@@ -202,6 +205,11 @@ public:
State state;
+ // only used when the "zero copy" style is used. Else readBuffer is used.
+ QSharedPointer< QVarLengthArray<char, 0> > downloadBufferArray;
+ char* downloadBuffer;
+ qint64 downloadBufferPosition;
+
Q_DECLARE_PUBLIC(QNetworkReplyImpl)
};
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index d3084cfdda..09ec4c2dd6 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -766,7 +766,7 @@ static QVariant parseCookieHeader(const QByteArray &raw)
result += parsed;
}
- return qVariantFromValue(result);
+ return QVariant::fromValue(result);
}
static QVariant parseHeaderValue(QNetworkRequest::KnownHeaders header, const QByteArray &value)
@@ -799,7 +799,7 @@ static QVariant parseHeaderValue(QNetworkRequest::KnownHeaders header, const QBy
return parseCookieHeader(value);
case QNetworkRequest::SetCookieHeader:
- return qVariantFromValue(QNetworkCookie::parseCookies(value));
+ return QVariant::fromValue(QNetworkCookie::parseCookies(value));
default:
Q_ASSERT(0);
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 348b0d2a7a..7908182d13 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -56,9 +56,7 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_THREAD
Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager)
-#endif
//#define QHOSTINFO_DEBUG
@@ -87,10 +85,8 @@ Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager)
\snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 0
- The slot is invoked when the results are ready. (If you use
- Qt for Embedded Linux and disabled multithreading support by defining
- \c QT_NO_THREAD, lookupHost() will block until the lookup has
- finished.) The results are stored in a QHostInfo object. Call
+ The slot is invoked when the results are ready. The results are
+ stored in a QHostInfo object. Call
addresses() to get the list of IP addresses for the host, and
hostName() to get the host name that was looked up.
@@ -176,14 +172,6 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
return id;
}
-#ifdef QT_NO_THREAD
- QHostInfo hostInfo = QHostInfoAgent::fromName(name);
- hostInfo.setLookupId(id);
- QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
- QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
- receiver, member, Qt::QueuedConnection);
- result.data()->emitResultsReady(hostInfo);
-#else
QHostInfoLookupManager *manager = theHostInfoLookupManager();
if (manager) {
// the application is still alive
@@ -204,8 +192,6 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
manager->scheduleLookup(runnable);
}
-#endif
-
return id;
}
@@ -216,12 +202,7 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
*/
void QHostInfo::abortHostLookup(int id)
{
-#ifndef QT_NO_THREAD
theHostInfoLookupManager()->abortLookup(id);
-#else
- // we cannot abort if it was non threaded.. the result signal has already been posted
- Q_UNUSED(id);
-#endif
}
/*!
@@ -422,7 +403,6 @@ void QHostInfo::setErrorString(const QString &str)
\sa hostName()
*/
-#ifndef QT_NO_THREAD
QHostInfoRunnable::QHostInfoRunnable(QString hn, int i) : toBeLookedUp(hn), id(i)
{
setAutoDelete(true);
@@ -747,6 +727,4 @@ void QHostInfoCache::clear()
cache.clear();
}
-#endif // QT_NO_THREAD
-
QT_END_NAMESPACE
diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h
index 85d14c295b..134335f8cc 100644
--- a/src/network/kernel/qhostinfo_p.h
+++ b/src/network/kernel/qhostinfo_p.h
@@ -60,8 +60,6 @@
#include "QtCore/qwaitcondition.h"
#include "QtCore/qobject.h"
#include "QtCore/qpointer.h"
-
-#ifndef QT_NO_THREAD
#include "QtCore/qthread.h"
#include "QtCore/qthreadpool.h"
#include "QtCore/qmutex.h"
@@ -70,7 +68,7 @@
#include "QtCore/qqueue.h"
#include <QTime>
#include <QCache>
-#endif
+
QT_BEGIN_NAMESPACE
@@ -112,7 +110,6 @@ public:
int lookupId;
};
-#ifndef QT_NO_THREAD
// These functions are outside of the QHostInfo class and strictly internal.
// Do NOT use them outside of QAbstractSocket.
QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id);
@@ -192,8 +189,6 @@ private slots:
void waitForThreadPoolDone() { threadPool.waitForDone(); }
};
-#endif
-
QT_END_NAMESPACE
#endif // QHOSTINFO_P_H
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 9e3da612c2..5ca15a3e44 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -132,9 +132,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
// Load res_init on demand.
static volatile bool triedResolve = false;
if (!triedResolve) {
-#ifndef QT_NO_THREAD
QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_init));
-#endif
if (!triedResolve) {
resolveLibrary();
triedResolve = true;
diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp
index 8241c84a0f..8e28fb3273 100644
--- a/src/network/kernel/qhostinfo_win.cpp
+++ b/src/network/kernel/qhostinfo_win.cpp
@@ -39,11 +39,6 @@
**
****************************************************************************/
-#if defined Q_CC_MSVC && _MSC_VER <=1300
-//VC.net 2002 support for templates doesn't match some PSDK requirements
-#define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
-#endif
-
#include <winsock2.h>
#include "qhostinfo_p.h"
@@ -115,9 +110,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
// Load res_init on demand.
static volatile bool triedResolve = false;
if (!triedResolve) {
-#ifndef QT_NO_THREAD
QMutexLocker locker(QMutexPool::globalInstanceGet(&local_getaddrinfo));
-#endif
if (!triedResolve) {
resolveLibrary();
triedResolve = true;
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 505db71e69..66cdffb26e 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -356,6 +356,10 @@
to enable.
\value KeepAliveOption Set this to 1 to enable the SO_KEEPALIVE socket option
+ \value MulticastTtlOption Set this to an integer value to set IP_MULTICAST_TTL (TTL for multicast datagrams) socket option.
+
+ \value MulticastLoopbackOption Set this to 1 to enable the IP_MULTICAST_LOOP (multicast loopback) socket option.
+
\sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption()
*/
@@ -466,9 +470,6 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
peerPort(0),
socketEngine(0),
cachedSocketDescriptor(-1),
-#ifdef Q_OS_LINUX
- addToBytesAvailable(0),
-#endif
readBufferMaxSize(0),
readBuffer(QABSTRACTSOCKET_BUFFERSIZE),
writeBuffer(QABSTRACTSOCKET_BUFFERSIZE),
@@ -630,8 +631,9 @@ bool QAbstractSocketPrivate::canReadNotification()
// only emit readyRead() when not recursing, and only if there is data available
bool hasData = newBytes > 0
#ifndef QT_NO_UDPSOCKET
- || (!isBuffered && socketEngine && socketEngine->hasPendingDatagrams())
+ || (!isBuffered && socketType != QAbstractSocket::TcpSocket && socketEngine && socketEngine->hasPendingDatagrams())
#endif
+ || (!isBuffered && socketType == QAbstractSocket::TcpSocket && socketEngine)
;
if (!emittedReadyRead && hasData) {
@@ -1132,10 +1134,6 @@ bool QAbstractSocketPrivate::readFromSocket()
Q_Q(QAbstractSocket);
// Find how many bytes we can read from the socket layer.
qint64 bytesToRead = socketEngine->bytesAvailable();
-#ifdef Q_OS_LINUX
- if (bytesToRead > 0) // ### See setSocketDescriptor()
- bytesToRead += addToBytesAvailable;
-#endif
if (bytesToRead == 0) {
// Under heavy load, certain conditions can trigger read notifications
// for socket notifiers on which there is no activity. If we continue
@@ -1340,10 +1338,6 @@ void QAbstractSocket::connectToHostImplementation(const QString &hostName, quint
d->localAddress.clear();
d->peerAddress.clear();
d->peerName = hostName;
-#ifdef Q_OS_LINUX
- // ### See setSocketDescriptor().
- d->addToBytesAvailable = 0;
-#endif
if (d->hostLookupId != -1) {
QHostInfo::abortHostLookup(d->hostLookupId);
d->hostLookupId = -1;
@@ -1361,8 +1355,11 @@ void QAbstractSocket::connectToHostImplementation(const QString &hostName, quint
}
#endif
- if (!d_func()->isBuffered)
- openMode |= QAbstractSocket::Unbuffered;
+ if (openMode & QIODevice::Unbuffered)
+ d->isBuffered = false; // Unbuffered QTcpSocket
+ else if (!d_func()->isBuffered)
+ openMode |= QAbstractSocket::Unbuffered; // QUdpSocket
+
QIODevice::open(openMode);
d->state = HostLookupState;
emit stateChanged(d->state);
@@ -1442,10 +1439,12 @@ qint64 QAbstractSocket::bytesAvailable() const
{
Q_D(const QAbstractSocket);
qint64 available = QIODevice::bytesAvailable();
- if (d->isBuffered)
- available += (qint64) d->readBuffer.size();
- else if (d->socketEngine && d->socketEngine->isValid())
+
+ available += (qint64) d->readBuffer.size();
+
+ if (!d->isBuffered && d->socketEngine && d->socketEngine->isValid())
available += d->socketEngine->bytesAvailable();
+
#if defined(QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocket::bytesAvailable() == %llu", available);
#endif
@@ -1603,17 +1602,6 @@ bool QAbstractSocket::setSocketDescriptor(int socketDescriptor, SocketState sock
d->peerAddress = d->socketEngine->peerAddress();
d->cachedSocketDescriptor = socketDescriptor;
-#ifdef Q_OS_LINUX
- // ### This is a workaround for certain broken Linux kernels, when using
- // QTcpSocket with a Unix domain socket. It was introduced around 2.6.9,
- // and fixed at some point after that.
- // http://archive.linux-usenet.com/index-t-73300.html
- // We can provide a better workaround for this: readFromSocket() can loop
- // while reading, but this must happen without triggering an implicit
- // close because of reading after the socket has closed.
- d->addToBytesAvailable = 4096;
-#endif
-
return true;
}
@@ -1643,6 +1631,14 @@ void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, cons
case KeepAliveOption:
d_func()->socketEngine->setOption(QAbstractSocketEngine::KeepAliveOption, value.toInt());
break;
+
+ case MulticastTtlOption:
+ d_func()->socketEngine->setOption(QAbstractSocketEngine::MulticastTtlOption, value.toInt());
+ break;
+
+ case MulticastLoopbackOption:
+ d_func()->socketEngine->setOption(QAbstractSocketEngine::MulticastLoopbackOption, value.toInt());
+ break;
}
}
@@ -1672,6 +1668,13 @@ QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option)
case KeepAliveOption:
ret = d_func()->socketEngine->option(QAbstractSocketEngine::KeepAliveOption);
break;
+
+ case MulticastTtlOption:
+ ret = d_func()->socketEngine->option(QAbstractSocketEngine::MulticastTtlOption);
+ break;
+ case MulticastLoopbackOption:
+ ret = d_func()->socketEngine->option(QAbstractSocketEngine::MulticastLoopbackOption);
+ break;
}
if (ret == -1)
return QVariant();
@@ -2089,42 +2092,50 @@ bool QAbstractSocket::flush()
qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
{
Q_D(QAbstractSocket);
- if (d->socketEngine && !d->socketEngine->isReadNotificationEnabled() && d->socketEngine->isValid())
- d->socketEngine->setReadNotificationEnabled(true);
- if (!d->isBuffered) {
- if (!d->socketEngine)
- return -1; // no socket engine is probably EOF
- qint64 readBytes = d->socketEngine->read(data, maxSize);
- if (readBytes < 0) {
- d->socketError = d->socketEngine->error();
- setErrorString(d->socketEngine->errorString());
- }
- if (!d->socketEngine->isReadNotificationEnabled())
- d->socketEngine->setReadNotificationEnabled(true);
-#if defined (QABSTRACTSOCKET_DEBUG)
- qDebug("QAbstractSocket::readData(%p \"%s\", %lli) == %lld",
- data, qt_prettyDebug(data, 32, readBytes).data(), maxSize,
- readBytes);
-#endif
- return readBytes;
- }
-
- if (d->readBuffer.isEmpty())
+ // This is for a buffered QTcpSocket
+ if (d->isBuffered && d->readBuffer.isEmpty())
// if we're still connected, return 0 indicating there may be more data in the future
// if we're not connected, return -1 indicating EOF
return d->state == QAbstractSocket::ConnectedState ? qint64(0) : qint64(-1);
- // If readFromSocket() read data, copy it to its destination.
- if (maxSize == 1) {
+ // short cut for a char read if we have something in the buffer
+ if (maxSize == 1 && !d->readBuffer.isEmpty()) {
*data = d->readBuffer.getChar();
#if defined (QABSTRACTSOCKET_DEBUG)
- qDebug("QAbstractSocket::readData(%p '%c (0x%.2x)', 1) == 1",
+ qDebug("QAbstractSocket::readData(%p '%c (0x%.2x)', 1) == 1 [char buffer]",
data, isprint(int(uchar(*data))) ? *data : '?', *data);
#endif
+ if (d->readBuffer.isEmpty() && d->socketEngine)
+ d->socketEngine->setReadNotificationEnabled(true);
return 1;
}
+ // Special case for an Unbuffered QTcpSocket
+ // Re-filling the buffer.
+ if (d->socketType == TcpSocket
+ && !d->isBuffered
+ && d->readBuffer.size() < maxSize
+ && d->readBufferMaxSize > 0
+ && maxSize < d->readBufferMaxSize
+ && d->socketEngine) {
+ // Our buffer is empty and a read() was requested for a byte amount that is smaller
+ // than the readBufferMaxSize. This means that we should fill our buffer since we want
+ // such small reads come from the buffer and not always go to the costly socket engine read()
+ qint64 bytesToRead = d->socketEngine->bytesAvailable();
+ if (bytesToRead > 0) {
+ char *ptr = d->readBuffer.reserve(bytesToRead);
+ qint64 readBytes = d->socketEngine->read(ptr, bytesToRead);
+ if (readBytes == -2) {
+ // No bytes currently available for reading.
+ d->readBuffer.chop(bytesToRead);
+ } else {
+ d->readBuffer.chop(int(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes)));
+ }
+ }
+ }
+
+ // First try to satisfy the read from the buffer
qint64 bytesToRead = qMin(qint64(d->readBuffer.size()), maxSize);
qint64 readSoFar = 0;
while (readSoFar < bytesToRead) {
@@ -2136,8 +2147,50 @@ qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
d->readBuffer.free(bytesToReadFromThisBlock);
}
+ if (d->socketEngine && !d->socketEngine->isReadNotificationEnabled() && d->socketEngine->isValid())
+ d->socketEngine->setReadNotificationEnabled(true);
+
+ if (readSoFar > 0) {
+ // we read some data from buffer.
+ // Just return, readyRead will be emitted again
#if defined (QABSTRACTSOCKET_DEBUG)
- qDebug("QAbstractSocket::readData(%p \"%s\", %lli) == %lld",
+ qDebug("QAbstractSocket::readData(%p '%c (0x%.2x)', %lli) == %lli [buffer]",
+ data, isprint(int(uchar(*data))) ? *data : '?', *data, maxSize, readSoFar);
+#endif
+
+ if (d->readBuffer.isEmpty() && d->socketEngine)
+ d->socketEngine->setReadNotificationEnabled(true);
+ return readSoFar;
+ }
+
+ // This code path is for Unbuffered QTcpSocket or for connected UDP
+
+ if (!d->isBuffered) {
+ if (!d->socketEngine)
+ return -1; // no socket engine is probably EOF
+ qint64 readBytes = d->socketEngine->read(data, maxSize);
+ if (readBytes == -2) {
+ // -2 from the engine means no bytes available (EAGAIN) so read more later
+ return 0;
+ } else if (readBytes < 0) {
+ d->socketError = d->socketEngine->error();
+ setErrorString(d->socketEngine->errorString());
+ } else if (!d->socketEngine->isReadNotificationEnabled()) {
+ // Only do this when there was no error
+ d->socketEngine->setReadNotificationEnabled(true);
+ }
+
+#if defined (QABSTRACTSOCKET_DEBUG)
+ qDebug("QAbstractSocket::readData(%p \"%s\", %lli) == %lld [engine]",
+ data, qt_prettyDebug(data, 32, readBytes).data(), maxSize,
+ readBytes);
+#endif
+ return readBytes;
+ }
+
+
+#if defined (QABSTRACTSOCKET_DEBUG)
+ qDebug("QAbstractSocket::readData(%p \"%s\", %lli) == %lld [unreachable]",
data, qt_prettyDebug(data, qMin<qint64>(32, readSoFar), readSoFar).data(),
maxSize, readSoFar);
#endif
@@ -2162,7 +2215,23 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size)
return -1;
}
- if (!d->isBuffered) {
+ if (!d->isBuffered && d->socketType == TcpSocket && d->writeBuffer.isEmpty()) {
+ // This code is for the new Unbuffered QTcpSocket use case
+ qint64 written = d->socketEngine->write(data, size);
+ if (written < 0) {
+ d->socketError = d->socketEngine->error();
+ setErrorString(d->socketEngine->errorString());
+ return written;
+ } else if (written < size) {
+ // Buffer what was not written yet
+ char *ptr = d->writeBuffer.reserve(size - written);
+ memcpy(ptr, data + written, size - written);
+ if (d->socketEngine)
+ d->socketEngine->setWriteNotificationEnabled(true);
+ }
+ return size; // size=actually written + what has been buffered
+ } else if (!d->isBuffered && d->socketType != TcpSocket) {
+ // This is for a QUdpSocket that was connect()ed
qint64 written = d->socketEngine->write(data, size);
if (written < 0) {
d->socketError = d->socketEngine->error();
@@ -2181,6 +2250,12 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size)
return written;
}
+ // This is the code path for normal buffered QTcpSocket or
+ // unbuffered QTcpSocket when there was already something in the
+ // write buffer and therefore we could not do a direct engine write.
+ // We just write to our write buffer and enable the write notifier
+ // The write notifier then flush()es the buffer.
+
char *ptr = d->writeBuffer.reserve(size);
if (size == 1)
*ptr = *data;
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 9e487d2287..f610db363e 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -118,7 +118,9 @@ public:
};
enum SocketOption {
LowDelayOption, // TCP_NODELAY
- KeepAliveOption // SO_KEEPALIVE
+ KeepAliveOption, // SO_KEEPALIVE
+ MulticastTtlOption, // IP_MULTICAST_TTL
+ MulticastLoopbackOption // IP_MULTICAST_LOOPBACK
};
QAbstractSocket(SocketType socketType, QObject *parent);
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index b51c30161b..6c333d31ca 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -138,9 +138,6 @@ public:
void setupSocketNotifiers();
bool readFromSocket();
-#ifdef Q_OS_LINUX
- qint64 addToBytesAvailable;
-#endif
qint64 readBufferMaxSize;
QRingBuffer readBuffer;
QRingBuffer writeBuffer;
diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h
index 36698525d0..ec5fbd30c1 100644
--- a/src/network/socket/qabstractsocketengine_p.h
+++ b/src/network/socket/qabstractsocketengine_p.h
@@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
class QAuthenticator;
class QAbstractSocketEnginePrivate;
+class QNetworkInterface;
class QNetworkProxy;
class QAbstractSocketEngineReceiver {
@@ -94,7 +95,9 @@ public:
BindExclusively,
ReceiveOutOfBandData,
LowDelayOption,
- KeepAliveOption
+ KeepAliveOption,
+ MulticastTtlOption,
+ MulticastLoopbackOption
};
virtual bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) = 0;
@@ -118,6 +121,13 @@ public:
virtual qint64 write(const char *data, qint64 len) = 0;
#ifndef QT_NO_UDPSOCKET
+ virtual bool joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface) = 0;
+ virtual bool leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface) = 0;
+ virtual QNetworkInterface multicastInterface() const = 0;
+ virtual bool setMulticastInterface(const QNetworkInterface &iface) = 0;
+
virtual qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
quint16 *port = 0) = 0;
virtual qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index dfda257854..cb0e2961f8 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -45,6 +45,7 @@
#include "qurl.h"
#include "qhttp.h"
#include "qelapsedtimer.h"
+#include "qnetworkinterface.h"
#if !defined(QT_NO_NETWORKPROXY) && !defined(QT_NO_HTTP)
#include <qdebug.h>
@@ -239,6 +240,34 @@ qint64 QHttpSocketEngine::write(const char *data, qint64 len)
}
#ifndef QT_NO_UDPSOCKET
+bool QHttpSocketEngine::joinMulticastGroup(const QHostAddress &,
+ const QNetworkInterface &)
+{
+ setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QLatin1String("Operation on socket is not supported"));
+ return false;
+}
+
+bool QHttpSocketEngine::leaveMulticastGroup(const QHostAddress &,
+ const QNetworkInterface &)
+{
+ setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QLatin1String("Operation on socket is not supported"));
+ return false;
+}
+
+QNetworkInterface QHttpSocketEngine::multicastInterface() const
+{
+ return QNetworkInterface();
+}
+
+bool QHttpSocketEngine::setMulticastInterface(const QNetworkInterface &)
+{
+ setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QLatin1String("Operation on socket is not supported"));
+ return false;
+}
+
qint64 QHttpSocketEngine::readDatagram(char *, qint64, QHostAddress *,
quint16 *)
{
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index 5051def87b..b68b7117a0 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -102,6 +102,13 @@ public:
qint64 write(const char *data, qint64 len);
#ifndef QT_NO_UDPSOCKET
+ bool joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &interface);
+ bool leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &interface);
+ QNetworkInterface multicastInterface() const;
+ bool setMulticastInterface(const QNetworkInterface &iface);
+
qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
quint16 *port = 0);
qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp
index a169ca0947..df73b9cd0e 100644
--- a/src/network/socket/qnativesocketengine.cpp
+++ b/src/network/socket/qnativesocketengine.cpp
@@ -98,6 +98,7 @@
#include <qabstracteventdispatcher.h>
#include <qsocketnotifier.h>
+#include <qnetworkinterface.h>
#include "qnativesocketengine_p.h"
#include <private/qthread_p.h>
@@ -647,6 +648,51 @@ int QNativeSocketEngine::accept()
}
/*!
+ \since 4.8
+*/
+bool QNativeSocketEngine::joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface)
+{
+ Q_D(QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::joinMulticastGroup(), false);
+ Q_CHECK_STATE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::BoundState, false);
+ Q_CHECK_TYPE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::UdpSocket, false);
+ return d->nativeJoinMulticastGroup(groupAddress, iface);
+}
+
+/*!
+ \since 4.8
+*/
+bool QNativeSocketEngine::leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface)
+{
+ Q_D(QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::leaveMulticastGroup(), false);
+ Q_CHECK_STATE(QNativeSocketEngine::leaveMulticastGroup(), QAbstractSocket::BoundState, false);
+ Q_CHECK_TYPE(QNativeSocketEngine::leaveMulticastGroup(), QAbstractSocket::UdpSocket, false);
+ return d->nativeLeaveMulticastGroup(groupAddress, iface);
+}
+
+/*! \since 4.8 */
+QNetworkInterface QNativeSocketEngine::multicastInterface() const
+{
+ Q_D(const QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::multicastInterface(), QNetworkInterface());
+ Q_CHECK_TYPE(QNativeSocketEngine::multicastInterface(), QAbstractSocket::UdpSocket, QNetworkInterface());
+ return d->nativeMulticastInterface();
+}
+
+
+/*! \since 4.8 */
+bool QNativeSocketEngine::setMulticastInterface(const QNetworkInterface &iface)
+{
+ Q_D(QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setMulticastInterface(), false);
+ Q_CHECK_TYPE(QNativeSocketEngine::setMulticastInterface(), QAbstractSocket::UdpSocket, false);
+ return d->nativeSetMulticastInterface(iface);
+}
+
+/*!
Returns the number of bytes that are currently available for
reading. On error, -1 is returned.
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index eca16f6225..9baacf06fc 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -101,6 +101,7 @@ union qt_sockaddr {
};
class QNativeSocketEnginePrivate;
+class QNetworkInterface;
class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine
{
@@ -123,6 +124,13 @@ public:
int accept();
void close();
+ bool joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+ bool leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+ QNetworkInterface multicastInterface() const;
+ bool setMulticastInterface(const QNetworkInterface &iface);
+
qint64 bytesAvailable() const;
qint64 read(char *data, qint64 maxlen);
@@ -237,6 +245,12 @@ public:
bool nativeBind(const QHostAddress &address, quint16 port);
bool nativeListen(int backlog);
int nativeAccept();
+ bool nativeJoinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+ bool nativeLeaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+ QNetworkInterface nativeMulticastInterface() const;
+ bool nativeSetMulticastInterface(const QNetworkInterface &iface);
qint64 nativeBytesAvailable() const;
bool nativeHasPendingDatagrams() const;
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index f6bfbac27c..aa55009aea 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -46,6 +46,7 @@
#include "qhostaddress.h"
#include "qelapsedtimer.h"
#include "qvarlengtharray.h"
+#include "qnetworkinterface.h"
#include <time.h>
#include <errno.h>
#include <fcntl.h>
@@ -247,6 +248,30 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
case QNativeSocketEngine::KeepAliveOption:
n = SO_KEEPALIVE;
break;
+ case QNativeSocketEngine::MulticastTtlOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_HOPS;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_TTL;
+ }
+ break;
+ case QNativeSocketEngine::MulticastLoopbackOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_LOOP;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_LOOP;
+ }
+ break;
}
int v = -1;
@@ -330,6 +355,30 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
case QNativeSocketEngine::KeepAliveOption:
n = SO_KEEPALIVE;
break;
+ case QNativeSocketEngine::MulticastTtlOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_HOPS;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_TTL;
+ }
+ break;
+ case QNativeSocketEngine::MulticastLoopbackOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_LOOP;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_LOOP;
+ }
+ break;
}
return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0;
@@ -579,6 +628,171 @@ int QNativeSocketEnginePrivate::nativeAccept()
return acceptedDescriptor;
}
+
+static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d,
+ int how6,
+ int how4,
+ const QHostAddress &groupAddress,
+ const QNetworkInterface &interface)
+{
+ int level = 0;
+ int sockOpt = 0;
+ void *sockArg;
+ int sockArgSize;
+
+ ip_mreq mreq4;
+#ifndef QT_NO_IPV6
+ ipv6_mreq mreq6;
+
+ if (groupAddress.protocol() == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ sockOpt = how6;
+ sockArg = &mreq6;
+ sockArgSize = sizeof(mreq6);
+ memset(&mreq6, 0, sizeof(mreq6));
+ Q_IPV6ADDR ip6 = groupAddress.toIPv6Address();
+ memcpy(&mreq6.ipv6mr_multiaddr, &ip6, sizeof(ip6));
+ mreq6.ipv6mr_interface = interface.index();
+ } else
+#endif
+ if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
+ level = IPPROTO_IP;
+ sockOpt = how4;
+ sockArg = &mreq4;
+ sockArgSize = sizeof(mreq4);
+ memset(&mreq4, 0, sizeof(mreq4));
+ mreq4.imr_multiaddr.s_addr = htonl(groupAddress.toIPv4Address());
+
+ if (interface.isValid()) {
+ QList<QNetworkAddressEntry> addressEntries = interface.addressEntries();
+ if (!addressEntries.isEmpty()) {
+ QHostAddress firstIP = addressEntries.first().ip();
+ mreq4.imr_interface.s_addr = htonl(firstIP.toIPv4Address());
+ } else {
+ d->setError(QAbstractSocket::NetworkError,
+ QNativeSocketEnginePrivate::NetworkUnreachableErrorString);
+ return false;
+ }
+ } else {
+ mreq4.imr_interface.s_addr = INADDR_ANY;
+ }
+ } else {
+ // unreachable
+ d->setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QNativeSocketEnginePrivate::ProtocolUnsupportedErrorString);
+ return false;
+ }
+
+ int res = setsockopt(d->socketDescriptor, level, sockOpt, sockArg, sockArgSize);
+ if (res == -1) {
+ switch (errno) {
+ case ENOPROTOOPT:
+ d->setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QNativeSocketEnginePrivate::OperationUnsupportedErrorString);
+ break;
+ case EADDRNOTAVAIL:
+ d->setError(QAbstractSocket::SocketAddressNotAvailableError,
+ QNativeSocketEnginePrivate::AddressNotAvailableErrorString);
+ break;
+ default:
+ d->setError(QAbstractSocket::UnknownSocketError,
+ QNativeSocketEnginePrivate::UnknownSocketErrorString);
+ break;
+ }
+ return false;
+ }
+ return true;
+}
+
+bool QNativeSocketEnginePrivate::nativeJoinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &interface)
+{
+ return multicastMembershipHelper(this,
+#ifndef QT_NO_IPV6
+ IPV6_JOIN_GROUP,
+#else
+ 0,
+#endif
+ IP_ADD_MEMBERSHIP,
+ groupAddress,
+ interface);
+}
+
+bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &interface)
+{
+ return multicastMembershipHelper(this,
+#ifndef QT_NO_IPV6
+ IPV6_LEAVE_GROUP,
+#else
+ 0,
+#endif
+ IP_DROP_MEMBERSHIP,
+ groupAddress,
+ interface);
+}
+
+QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
+{
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ uint v;
+ QT_SOCKOPTLEN_T sizeofv = sizeof(v);
+ if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, &sizeofv) == -1)
+ return QNetworkInterface();
+ return QNetworkInterface::interfaceFromIndex(v);
+ }
+#endif
+
+ struct in_addr v = { 0 };
+ QT_SOCKOPTLEN_T sizeofv = sizeof(v);
+ if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, &sizeofv) == -1)
+ return QNetworkInterface();
+ if (v.s_addr != 0 && sizeofv >= sizeof(v)) {
+ QHostAddress ipv4(ntohl(v.s_addr));
+ QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
+ for (int i = 0; i < ifaces.count(); ++i) {
+ const QNetworkInterface &iface = ifaces.at(i);
+ QList<QNetworkAddressEntry> entries = iface.addressEntries();
+ for (int j = 0; j < entries.count(); ++j) {
+ const QNetworkAddressEntry &entry = entries.at(j);
+ if (entry.ip() == ipv4)
+ return iface;
+ }
+ }
+ }
+ return QNetworkInterface();
+}
+
+bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface)
+{
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ uint v = iface.index();
+ return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, sizeof(v)) != -1);
+ }
+#endif
+
+ struct in_addr v;
+ if (iface.isValid()) {
+ QList<QNetworkAddressEntry> entries = iface.addressEntries();
+ for (int i = 0; i < entries.count(); ++i) {
+ const QNetworkAddressEntry &entry = entries.at(i);
+ const QHostAddress &ip = entry.ip();
+ if (ip.protocol() == QAbstractSocket::IPv4Protocol) {
+ v.s_addr = htonl(ip.toIPv4Address());
+ int r = ::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, sizeof(v));
+ if (r != -1)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ v.s_addr = INADDR_ANY;
+ return (::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, sizeof(v)) != -1);
+}
+
qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const
{
int nbytes = 0;
@@ -890,7 +1104,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize)
{
Q_Q(QNativeSocketEngine);
if (!q->isValid()) {
- qWarning("QNativeSocketEngine::unbufferedRead: Invalid socket");
+ qWarning("QNativeSocketEngine::nativeRead: Invalid socket");
return -1;
}
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 477ef45b12..f952cee574 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <winsock2.h>
+#include <ws2tcpip.h>
#include "qnativesocketengine_p.h"
@@ -47,6 +48,7 @@
#include <qsocketnotifier.h>
#include <qdebug.h>
#include <qdatetime.h>
+#include <qnetworkinterface.h>
//#define QNATIVESOCKETENGINE_DEBUG
#if defined(QNATIVESOCKETENGINE_DEBUG)
@@ -399,6 +401,30 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
case QNativeSocketEngine::KeepAliveOption:
n = SO_KEEPALIVE;
break;
+ case QNativeSocketEngine::MulticastTtlOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_HOPS;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_TTL;
+ }
+ break;
+ case QNativeSocketEngine::MulticastLoopbackOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_LOOP;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_LOOP;
+ }
+ break;
}
int v = -1;
@@ -459,6 +485,30 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
case QNativeSocketEngine::KeepAliveOption:
n = SO_KEEPALIVE;
break;
+ case QNativeSocketEngine::MulticastTtlOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_HOPS;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_TTL;
+ }
+ break;
+ case QNativeSocketEngine::MulticastLoopbackOption:
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ n = IPV6_MULTICAST_LOOP;
+ } else
+#endif
+ {
+ level = IPPROTO_IP;
+ n = IP_MULTICAST_LOOP;
+ }
+ break;
}
if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) {
@@ -648,8 +698,24 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
}
-bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 port)
+bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &a, quint16 port)
{
+ QHostAddress address = a;
+ switch (address.protocol()) {
+ case QAbstractSocket::IPv6Protocol:
+ if (address.toIPv6Address()[0] == 0xff) {
+ // binding to a multicast address
+ address = QHostAddress(QHostAddress::AnyIPv6);
+ }
+ break;
+ case QAbstractSocket::IPv4Protocol:
+ if ((address.toIPv4Address() & 0xffff0000) == 0xefff0000) {
+ // binding to a multicast address
+ address = QHostAddress(QHostAddress::Any);
+ }
+ break;
+ }
+
struct sockaddr_in sockAddrIPv4;
qt_sockaddr_in6 sockAddrIPv6;
struct sockaddr *sockAddrPtr = 0;
@@ -747,6 +813,159 @@ int QNativeSocketEnginePrivate::nativeAccept()
return acceptedDescriptor;
}
+static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d,
+ int how6,
+ int how4,
+ const QHostAddress &groupAddress,
+ const QNetworkInterface &iface)
+{
+ int level = 0;
+ int sockOpt = 0;
+ char *sockArg;
+ int sockArgSize;
+
+ struct ip_mreq mreq4;
+#ifndef QT_NO_IPV6
+ struct ipv6_mreq mreq6;
+
+ if (groupAddress.protocol() == QAbstractSocket::IPv6Protocol) {
+ level = IPPROTO_IPV6;
+ sockOpt = how6;
+ sockArg = reinterpret_cast<char *>(&mreq6);
+ sockArgSize = sizeof(mreq6);
+ memset(&mreq6, 0, sizeof(mreq6));
+ Q_IPV6ADDR ip6 = groupAddress.toIPv6Address();
+ memcpy(&mreq6.ipv6mr_multiaddr, &ip6, sizeof(ip6));
+ mreq6.ipv6mr_interface = iface.index();
+ } else
+#endif
+ if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
+ level = IPPROTO_IP;
+ sockOpt = how4;
+ sockArg = reinterpret_cast<char *>(&mreq4);
+ sockArgSize = sizeof(mreq4);
+ memset(&mreq4, 0, sizeof(mreq4));
+ mreq4.imr_multiaddr.s_addr = htonl(groupAddress.toIPv4Address());
+
+ if (iface.isValid()) {
+ QList<QNetworkAddressEntry> addressEntries = iface.addressEntries();
+ if (!addressEntries.isEmpty()) {
+ QHostAddress firstIP = addressEntries.first().ip();
+ mreq4.imr_interface.s_addr = htonl(firstIP.toIPv4Address());
+ } else {
+ d->setError(QAbstractSocket::NetworkError,
+ QNativeSocketEnginePrivate::NetworkUnreachableErrorString);
+ return false;
+ }
+ } else {
+ mreq4.imr_interface.s_addr = INADDR_ANY;
+ }
+ } else {
+ // unreachable
+ d->setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QNativeSocketEnginePrivate::ProtocolUnsupportedErrorString);
+ return false;
+ }
+
+ int res = setsockopt(d->socketDescriptor, level, sockOpt, sockArg, sockArgSize);
+ if (res == -1) {
+ d->setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QNativeSocketEnginePrivate::OperationUnsupportedErrorString);
+ return false;
+ }
+ return true;
+}
+
+bool QNativeSocketEnginePrivate::nativeJoinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface)
+{
+ return multicastMembershipHelper(this,
+#ifndef QT_NO_IPV6
+ IPV6_JOIN_GROUP,
+#else
+ 0,
+#endif
+ IP_ADD_MEMBERSHIP,
+ groupAddress,
+ iface);
+}
+
+bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface)
+{
+ return multicastMembershipHelper(this,
+#ifndef QT_NO_IPV6
+ IPV6_LEAVE_GROUP,
+#else
+ 0,
+#endif
+ IP_DROP_MEMBERSHIP,
+ groupAddress,
+ iface);
+}
+
+QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
+{
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ uint v;
+ QT_SOCKOPTLEN_T sizeofv = sizeof(v);
+ if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, &sizeofv) == -1)
+ return QNetworkInterface();
+ return QNetworkInterface::interfaceFromIndex(v);
+ }
+#endif
+
+ struct in_addr v = { 0 };
+ QT_SOCKOPTLEN_T sizeofv = sizeof(v);
+ if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, &sizeofv) == -1)
+ return QNetworkInterface();
+ if (v.s_addr != 0 && sizeofv >= sizeof(v)) {
+ QHostAddress ipv4(ntohl(v.s_addr));
+ QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
+ for (int i = 0; i < ifaces.count(); ++i) {
+ const QNetworkInterface &iface = ifaces.at(i);
+ if (!(iface.flags() & QNetworkInterface::CanMulticast))
+ continue;
+ QList<QNetworkAddressEntry> entries = iface.addressEntries();
+ for (int j = 0; j < entries.count(); ++j) {
+ const QNetworkAddressEntry &entry = entries.at(j);
+ if (entry.ip() == ipv4)
+ return iface;
+ }
+ }
+ }
+ return QNetworkInterface();
+}
+
+bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface)
+{
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ uint v = iface.isValid() ? iface.index() : 0;
+ return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, sizeof(v)) != -1);
+ }
+#endif
+
+ struct in_addr v;
+ if (iface.isValid()) {
+ QList<QNetworkAddressEntry> entries = iface.addressEntries();
+ for (int i = 0; i < entries.count(); ++i) {
+ const QNetworkAddressEntry &entry = entries.at(i);
+ const QHostAddress &ip = entry.ip();
+ if (ip.protocol() == QAbstractSocket::IPv4Protocol) {
+ v.s_addr = htonl(ip.toIPv4Address());
+ int r = ::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, sizeof(v));
+ if (r != -1)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ v.s_addr = INADDR_ANY;
+ return (::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, sizeof(v)) != -1);
+}
qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const
{
diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp
index f68edfe926..17cf5b14ce 100644
--- a/src/network/socket/qsocks5socketengine.cpp
+++ b/src/network/socket/qsocks5socketengine.cpp
@@ -56,6 +56,7 @@
#include "qurl.h"
#include "qauthenticator.h"
#include <qendian.h>
+#include <qnetworkinterface.h>
QT_BEGIN_NAMESPACE
@@ -1544,6 +1545,35 @@ qint64 QSocks5SocketEngine::write(const char *data, qint64 len)
}
#ifndef QT_NO_UDPSOCKET
+bool QSocks5SocketEngine::joinMulticastGroup(const QHostAddress &,
+ const QNetworkInterface &)
+{
+ setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QLatin1String("Operation on socket is not supported"));
+ return false;
+}
+
+bool QSocks5SocketEngine::leaveMulticastGroup(const QHostAddress &,
+ const QNetworkInterface &)
+{
+ setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QLatin1String("Operation on socket is not supported"));
+ return false;
+}
+
+
+QNetworkInterface QSocks5SocketEngine::multicastInterface() const
+{
+ return QNetworkInterface();
+}
+
+bool QSocks5SocketEngine::setMulticastInterface(const QNetworkInterface &)
+{
+ setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QLatin1String("Operation on socket is not supported"));
+ return false;
+}
+
qint64 QSocks5SocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr,
quint16 *port)
{
diff --git a/src/network/socket/qsocks5socketengine_p.h b/src/network/socket/qsocks5socketengine_p.h
index 3d35b579f6..06fcad2b43 100644
--- a/src/network/socket/qsocks5socketengine_p.h
+++ b/src/network/socket/qsocks5socketengine_p.h
@@ -92,6 +92,13 @@ public:
qint64 write(const char *data, qint64 len);
#ifndef QT_NO_UDPSOCKET
+ bool joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &interface);
+ bool leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &interface);
+ QNetworkInterface multicastInterface() const;
+ bool setMulticastInterface(const QNetworkInterface &iface);
+
qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
quint16 *port = 0);
qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp
index d5366d3c52..5d8f4c0a2d 100644
--- a/src/network/socket/qudpsocket.cpp
+++ b/src/network/socket/qudpsocket.cpp
@@ -77,14 +77,23 @@
\snippet doc/src/snippets/code/src_network_socket_qudpsocket.cpp 0
+ QUdpSocket also supports UDP multicast. Use joinMulticastGroup() and
+ leaveMulticastGroup() to control group membership, and
+ QAbstractSocket::MulticastTtlOption and
+ QAbstractSocket::MulticastLoopbackOption to set the TTL and loopback socket
+ options. Use setMulticastInterface() to control the outgoing interface for
+ multicast datagrams, and multicastInterface() to query it.
+
With QUdpSocket, you can also establish a virtual connection to a
UDP server using connectToHost() and then use read() and write()
to exchange datagrams without specifying the receiver for each
datagram.
- The \l{network/broadcastsender}{Broadcast Sender} and
- \l{network/broadcastreceiver}{Broadcast Receiver} examples
- illustrate how to use QUdpSocket in applications.
+ The \l{network/broadcastsender}{Broadcast Sender},
+ \l{network/broadcastreceiver}{Broadcast Receiver},
+ \l{network/multicastsender}{Multicast Sender}, and
+ \l{network/multicastreceiver}{Multicast Receiver} examples illustrate how
+ to use QUdpSocket in applications.
\section1 Symbian Platform Security Requirements
@@ -145,6 +154,7 @@
*/
#include "qhostaddress.h"
+#include "qnetworkinterface.h"
#include "qabstractsocket_p.h"
#include "qudpsocket.h"
@@ -329,6 +339,112 @@ bool QUdpSocket::bind(quint16 port, BindMode mode)
}
/*!
+ \since 4.8
+
+ Joins the the multicast group specified by \a groupAddress on the default
+ interface chosen by the operating system. The socket must be in BoundState,
+ otherwise an error occurs.
+
+ This function returns true if successful; otherwise it returns false
+ and sets the socket error accordingly.
+
+ \sa leaveMulticastGroup()
+*/
+bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress)
+{
+ return joinMulticastGroup(groupAddress, QNetworkInterface());
+}
+
+/*!
+ \since 4.8
+ \overload
+
+ Joins the multicast group address \a groupAddress on the interface \a
+ iface.
+
+ \sa leaveMulticastGroup()
+*/
+bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface)
+{
+ Q_D(QUdpSocket);
+ QT_CHECK_BOUND("QUdpSocket::joinMulticastGroup()", false);
+ return d->socketEngine->joinMulticastGroup(groupAddress, iface);
+}
+
+/*!
+ \since 4.8
+
+ Leaves the multicast group specified by \a groupAddress on the default
+ interface chosen by the operating system. The socket must be in BoundState,
+ otherwise an error occurs.
+
+ This function returns true if successful; otherwise it returns false and
+ sets the socket error accordingly.
+
+ \sa joinMulticastGroup()
+*/
+bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress)
+{
+ return leaveMulticastGroup(groupAddress, QNetworkInterface());
+}
+
+/*!
+ \since 4.8
+ \overload
+
+ Leaves the multicast group specified by \a groupAddress on the interface \a
+ iface.
+
+ \sa joinMulticastGroup()
+*/
+bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface)
+{
+ QT_CHECK_BOUND("QUdpSocket::leaveMulticastGroup()", false);
+ return d_func()->socketEngine->leaveMulticastGroup(groupAddress, iface);
+}
+
+/*!
+ \since 4.8
+
+ Returns the interface for the outgoing interface for multicast datagrams.
+ This corresponds to the IP_MULTICAST_IF socket option for IPv4 sockets and
+ the IPV6_MULTICAST_IF socket option for IPv6 sockets. If no interface has
+ been previously set, this function returns an invalid QNetworkInterface.
+ The socket must be in BoundState, otherwise an invalid QNetworkInterface is
+ returned.
+
+ \sa setMulticastInterface()
+*/
+QNetworkInterface QUdpSocket::multicastInterface() const
+{
+ Q_D(const QUdpSocket);
+ QT_CHECK_BOUND("QUdpSocket::multicastInterface()", QNetworkInterface());
+ return d->socketEngine->multicastInterface();
+}
+
+/*!
+ \since 4.8
+
+ Sets the outgoing interface for multicast datagrams to the interface \a
+ iface. This corresponds to the IP_MULTICAST_IF socket option for IPv4
+ sockets and the IPV6_MULTICAST_IF socket option for IPv6 sockets. The
+ socket must be in BoundState, otherwise this function does nothing.
+
+ \sa multicastInterface(), joinMulticastGroup(), leaveMulticastGroup()
+*/
+void QUdpSocket::setMulticastInterface(const QNetworkInterface &iface)
+{
+ Q_D(QUdpSocket);
+ if (!isValid()) {
+ qWarning("QUdpSocket::setMulticastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState");
+ return;
+ }
+ d->socketEngine->setMulticastInterface(iface);
+}
+
+/*!
Returns true if at least one datagram is waiting to be read;
otherwise returns false.
diff --git a/src/network/socket/qudpsocket.h b/src/network/socket/qudpsocket.h
index f477306ba6..b277d3f6d3 100644
--- a/src/network/socket/qudpsocket.h
+++ b/src/network/socket/qudpsocket.h
@@ -53,6 +53,7 @@ QT_MODULE(Network)
#ifndef QT_NO_UDPSOCKET
+class QNetworkInterface;
class QUdpSocketPrivate;
class Q_NETWORK_EXPORT QUdpSocket : public QAbstractSocket
@@ -76,6 +77,16 @@ public:
bool bind(quint16 port, BindMode mode);
// ### Qt 5: Merge the bind functions
+ bool joinMulticastGroup(const QHostAddress &groupAddress);
+ bool joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+ bool leaveMulticastGroup(const QHostAddress &groupAddress);
+ bool leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+
+ QNetworkInterface multicastInterface() const;
+ void setMulticastInterface(const QNetworkInterface &iface);
+
bool hasPendingDatagrams() const;
qint64 pendingDatagramSize() const;
qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = 0, quint16 *port = 0);
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 40b3641708..4b5f53e0e8 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -46,24 +46,29 @@
#include <QMetaEnum>
#endif
+// #define QT_GL_SHARED_SHADER_DEBUG
QT_BEGIN_NAMESPACE
-static void qt_shared_shaders_free(void *data)
+class QGLShaderStorage
{
- delete reinterpret_cast<QGLEngineSharedShaders *>(data);
-}
+public:
+ QGLEngineSharedShaders *shadersForThread(const QGLContext *context) {
+ QGLContextGroupResource<QGLEngineSharedShaders> *&shaders = m_storage.localData();
+ if (!shaders)
+ shaders = new QGLContextGroupResource<QGLEngineSharedShaders>();
+ return shaders->value(context);
+ }
+
+private:
+ QThreadStorage<QGLContextGroupResource<QGLEngineSharedShaders> *> m_storage;
+};
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shared_shaders, (qt_shared_shaders_free))
+Q_GLOBAL_STATIC(QGLShaderStorage, qt_shader_storage);
QGLEngineSharedShaders *QGLEngineSharedShaders::shadersForContext(const QGLContext *context)
{
- QGLEngineSharedShaders *p = reinterpret_cast<QGLEngineSharedShaders *>(qt_shared_shaders()->value(context));
- if (!p) {
- QGLShareContextScope scope(context);
- qt_shared_shaders()->insert(context, p = new QGLEngineSharedShaders(context));
- }
- return p;
+ return qt_shader_storage()->shadersForThread(context);
}
const char* QGLEngineSharedShaders::qShaderSnippets[] = {
@@ -170,18 +175,20 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
source.clear();
source.append(qShaderSnippets[MainVertexShader]);
source.append(qShaderSnippets[PositionOnlyVertexShader]);
- vertexShader = new QGLShader(QGLShader::Vertex, context, this);
+ vertexShader = new QGLShader(QGLShader::Vertex, context, 0);
+ shaders.append(vertexShader);
if (!vertexShader->compileSourceCode(source))
qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile");
source.clear();
source.append(qShaderSnippets[MainFragmentShader]);
source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]);
- fragShader = new QGLShader(QGLShader::Fragment, context, this);
+ fragShader = new QGLShader(QGLShader::Fragment, context, 0);
+ shaders.append(fragShader);
if (!fragShader->compileSourceCode(source))
qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile");
- simpleShaderProg = new QGLShaderProgram(context, this);
+ simpleShaderProg = new QGLShaderProgram(context, 0);
simpleShaderProg->addShader(vertexShader);
simpleShaderProg->addShader(fragShader);
simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
@@ -198,18 +205,20 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
source.clear();
source.append(qShaderSnippets[MainWithTexCoordsVertexShader]);
source.append(qShaderSnippets[UntransformedPositionVertexShader]);
- vertexShader = new QGLShader(QGLShader::Vertex, context, this);
+ vertexShader = new QGLShader(QGLShader::Vertex, context, 0);
+ shaders.append(vertexShader);
if (!vertexShader->compileSourceCode(source))
qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile");
source.clear();
source.append(qShaderSnippets[MainFragmentShader]);
source.append(qShaderSnippets[ImageSrcFragmentShader]);
- fragShader = new QGLShader(QGLShader::Fragment, context, this);
+ fragShader = new QGLShader(QGLShader::Fragment, context, 0);
+ shaders.append(fragShader);
if (!fragShader->compileSourceCode(source))
qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile");
- blitShaderProg = new QGLShaderProgram(context, this);
+ blitShaderProg = new QGLShaderProgram(context, 0);
blitShaderProg->addShader(vertexShader);
blitShaderProg->addShader(fragShader);
blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
@@ -220,13 +229,21 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
<< simpleShaderProg->log();
}
+#ifdef QT_GL_SHARED_SHADER_DEBUG
+ qDebug(" -> QGLEngineSharedShaders() %p for thread %p.", this, QThread::currentThread());
+#endif
}
QGLEngineSharedShaders::~QGLEngineSharedShaders()
{
- QList<QGLEngineShaderProg*>::iterator itr;
- for (itr = cachedPrograms.begin(); itr != cachedPrograms.end(); ++itr)
- delete *itr;
+#ifdef QT_GL_SHARED_SHADER_DEBUG
+ qDebug(" -> ~QGLEngineSharedShaders() %p for thread %p.", this, QThread::currentThread());
+#endif
+ qDeleteAll(shaders);
+ shaders.clear();
+
+ qDeleteAll(cachedPrograms);
+ cachedPrograms.clear();
if (blitShaderProg) {
delete blitShaderProg;
@@ -276,7 +293,8 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
source.append(qShaderSnippets[prog.compositionFragShader]);
if (prog.maskFragShader)
source.append(qShaderSnippets[prog.maskFragShader]);
- fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this);
+ fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), 0);
+ shaders.append(fragShader);
QByteArray description;
#if defined(QT_DEBUG)
// Name the shader for easier debugging
@@ -302,7 +320,8 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
source.clear();
source.append(qShaderSnippets[prog.mainVertexShader]);
source.append(qShaderSnippets[prog.positionVertexShader]);
- vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this);
+ vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), 0);
+ shaders.append(vertexShader);
#if defined(QT_DEBUG)
// Name the shader for easier debugging
description.clear();
@@ -320,7 +339,7 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
newProg = new QGLEngineShaderProg(prog);
// If the shader program's not found in the cache, create it now.
- newProg->program = new QGLShaderProgram(ctxGuard.context(), this);
+ newProg->program = new QGLShaderProgram(ctxGuard.context(), 0);
newProg->program->addShader(vertexShader);
newProg->program->addShader(fragShader);
@@ -413,7 +432,6 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
currentShaderProg(0)
{
sharedShaders = QGLEngineSharedShaders::shadersForContext(context);
- connect(sharedShaders, SIGNAL(shaderProgNeedsChanging()), this, SLOT(shaderProgNeedsChangingSlot()));
}
QGLEngineShaderManager::~QGLEngineShaderManager()
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 06b96ae60c..e5ababff32 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -259,9 +259,9 @@ static const GLuint QT_PMV_MATRIX_3_ATTR = 5;
class QGLEngineShaderProg;
-class QGLEngineSharedShaders : public QObject
+class QGLEngineSharedShaders
{
- Q_OBJECT
+ Q_GADGET
public:
enum SnippetName {
@@ -364,14 +364,12 @@ public:
// full.
void cleanupCustomStage(QGLCustomShaderStage* stage);
-signals:
- void shaderProgNeedsChanging();
-
private:
QGLSharedResourceGuard ctxGuard;
QGLShaderProgram *blitShaderProg;
QGLShaderProgram *simpleShaderProg;
QList<QGLEngineShaderProg*> cachedPrograms;
+ QList<QGLShader *> shaders;
static const char* qShaderSnippets[TotalSnippetCount];
};
@@ -492,9 +490,6 @@ public:
QGLEngineSharedShaders* sharedShaders;
-private slots:
- void shaderProgNeedsChangingSlot() { shaderProgNeedsChanging = true; }
-
private:
QGLContext* ctx;
bool shaderProgNeedsChanging;
diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp
index a1495dd8a9..cbd5eb8b4c 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache.cpp
+++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp
@@ -42,29 +42,33 @@
#include "qglgradientcache_p.h"
#include <private/qdrawhelper_p.h>
#include <private/qgl_p.h>
-
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
-static void QGL2GradientCache_free(void *ptr)
+class QGL2GradientCacheWrapper
{
- delete reinterpret_cast<QGL2GradientCache *>(ptr);
-}
+public:
+ QGL2GradientCache *cacheForContext(const QGLContext *context) {
+ QMutexLocker lock(&m_mutex);
+ return m_resource.value(context);
+ }
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_gradient_caches, (QGL2GradientCache_free))
+private:
+ QGLContextGroupResource<QGL2GradientCache> m_resource;
+ QMutex m_mutex;
+};
+
+Q_GLOBAL_STATIC(QGL2GradientCacheWrapper, qt_gradient_caches)
QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context)
{
- QGL2GradientCache *p = reinterpret_cast<QGL2GradientCache *>(qt_gradient_caches()->value(context));
- if (!p) {
- QGLShareContextScope scope(context);
- p = new QGL2GradientCache;
- qt_gradient_caches()->insert(context, p);
- }
- return p;
+ return qt_gradient_caches()->cacheForContext(context);
}
-void QGL2GradientCache::cleanCache() {
+void QGL2GradientCache::cleanCache()
+{
+ QMutexLocker lock(&m_mutex);
QGLGradientColorTableHash::const_iterator it = cache.constBegin();
for (; it != cache.constEnd(); ++it) {
const CacheInfo &cache_info = it.value();
@@ -75,6 +79,7 @@ void QGL2GradientCache::cleanCache() {
GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity)
{
+ QMutexLocker lock(&m_mutex);
quint64 hash_val = 0;
QGradientStops stops = gradient.stops();
@@ -88,7 +93,9 @@ GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity)
else {
do {
const CacheInfo &cache_info = it.value();
- if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode()) {
+ if (cache_info.stops == stops && cache_info.opacity == opacity
+ && cache_info.interpolationMode == gradient.interpolationMode())
+ {
return cache_info.texId;
}
++it;
diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h
index 0a5f846af8..7e93d87571 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache_p.h
+++ b/src/opengl/gl2paintengineex/qglgradientcache_p.h
@@ -54,6 +54,7 @@
#include <QObject>
#include <QtOpenGL/QtOpenGL>
#include <private/qgl_p.h>
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -75,22 +76,22 @@ class QGL2GradientCache
public:
static QGL2GradientCache *cacheForContext(const QGLContext *context);
- QGL2GradientCache() { }
- ~QGL2GradientCache() {cleanCache();}
+ QGL2GradientCache(const QGLContext *) {}
+ ~QGL2GradientCache() { cleanCache(); }
GLuint getBuffer(const QGradient &gradient, qreal opacity);
inline int paletteSize() const { return 1024; }
-protected:
+private:
inline int maxCacheSize() const { return 60; }
inline void generateGradientColorTable(const QGradient& gradient,
uint *colorTable,
int size, qreal opacity) const;
GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity);
-
void cleanCache();
QGLGradientColorTableHash cache;
+ QMutex m_mutex;
};
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 2347e668b8..d89ef08d90 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1493,16 +1493,18 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
QOpenGL2PaintEngineState *s = q->state();
+ void *cacheKey = const_cast<QGLContext *>(QGLContextPrivate::contextGroup(ctx)->context());
QGLTextureGlyphCache *cache =
- (QGLTextureGlyphCache *) staticTextItem->fontEngine->glyphCache(ctx, glyphType, QTransform());
+ (QGLTextureGlyphCache *) staticTextItem->fontEngine->glyphCache(cacheKey, glyphType, QTransform());
if (!cache || cache->cacheType() != glyphType) {
cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform());
- staticTextItem->fontEngine->setGlyphCache(ctx, cache);
+ staticTextItem->fontEngine->setGlyphCache(cacheKey, cache);
}
cache->setPaintEnginePrivate(this);
cache->populate(staticTextItem->fontEngine, staticTextItem->numGlyphs, staticTextItem->glyphs,
staticTextItem->glyphPositions);
+ cache->fillInPendingGlyphs();
if (cache->width() == 0 || cache->height() == 0)
return;
@@ -1549,8 +1551,15 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
vertexCoordinates->clear();
textureCoordinates->clear();
+ bool supportsSubPixelPositions = staticTextItem->fontEngine->supportsSubPixelPositions();
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
- const QTextureGlyphCache::Coord &c = cache->coords.value(staticTextItem->glyphs[i]);
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions)
+ subPixelPosition = cache->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
+
+ QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
+
+ const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
int x = staticTextItem->glyphPositions[i].x.toInt() + c.baseLineX - margin;
int y = staticTextItem->glyphPositions[i].y.toInt() - c.baseLineY - margin;
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index 410cf21321..3dc778971d 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -52,43 +52,41 @@ QT_BEGIN_NAMESPACE
extern Q_GUI_EXPORT bool qt_cleartype_enabled;
#endif
-QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
+QGLTextureGlyphCache::QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
: QImageTextureGlyphCache(type, matrix)
- , ctx(context)
- , m_width(0)
- , m_height(0)
+ , ctx(0)
+ , pex(0)
{
- // broken FBO readback is a bug in the SGX 1.3 and 1.4 drivers for the N900 where
- // copying between FBO's is broken if the texture is either GL_ALPHA or POT. The
- // workaround is to use a system-memory copy of the glyph cache for this device.
- // Switching to NPOT and GL_RGBA would both cost a lot more graphics memory and
- // be slower, so that is not desireable.
- if (!ctx->d_ptr->workaround_brokenFBOReadBack)
- glGenFramebuffers(1, &m_fbo);
-
- connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(contextDestroyed(const QGLContext*)));
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, ctx);
+#endif
+ setContext(context);
}
QGLTextureGlyphCache::~QGLTextureGlyphCache()
{
- if (ctx) {
- QGLShareContextScope scope(ctx);
-
- if (!ctx->d_ptr->workaround_brokenFBOReadBack)
- glDeleteFramebuffers(1, &m_fbo);
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug(" -> ~QGLTextureGlyphCache() %p.", this);
+#endif
+}
- if (m_width || m_height)
- glDeleteTextures(1, &m_texture);
- }
+void QGLTextureGlyphCache::setContext(const QGLContext *context)
+{
+ ctx = context;
+ m_h = 0;
}
void QGLTextureGlyphCache::createTextureData(int width, int height)
{
+ if (ctx == 0) {
+ qWarning("QGLTextureGlyphCache::createTextureData: Called with no context");
+ return;
+ }
+
// create in QImageTextureGlyphCache baseclass is meant to be called
// only to create the initial image and does not preserve the content,
// so we don't call when this function is called from resize.
- if (ctx->d_ptr->workaround_brokenFBOReadBack && image().isNull())
+ if ((pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) && image().isNull())
QImageTextureGlyphCache::createTextureData(width, height);
// Make the lower glyph texture size 16 x 16.
@@ -97,11 +95,12 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
if (height < 16)
height = 16;
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
+ QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
+ glGenTextures(1, &glyphTexture->m_texture);
+ glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
- m_width = width;
- m_height = height;
+ glyphTexture->m_width = width;
+ glyphTexture->m_height = height;
QVarLengthArray<uchar> data(width * height);
for (int i = 0; i < data.size(); ++i)
@@ -118,8 +117,14 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
void QGLTextureGlyphCache::resizeTextureData(int width, int height)
{
- int oldWidth = m_width;
- int oldHeight = m_height;
+ if (ctx == 0) {
+ qWarning("QGLTextureGlyphCache::resizeTextureData: Called with no context");
+ return;
+ }
+ QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
+
+ int oldWidth = glyphTexture->m_width;
+ int oldHeight = glyphTexture->m_height;
// Make the lower glyph texture size 16 x 16.
if (width < 16)
@@ -127,10 +132,10 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
if (height < 16)
height = 16;
- GLuint oldTexture = m_texture;
+ GLuint oldTexture = glyphTexture->m_texture;
createTextureData(width, height);
-
- if (ctx->d_ptr->workaround_brokenFBOReadBack) {
+
+ if (pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) {
QImageTextureGlyphCache::resizeTextureData(width, height);
Q_ASSERT(image().depth() == 8);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits());
@@ -141,7 +146,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
// ### the QTextureGlyphCache API needs to be reworked to allow
// ### resizeTextureData to fail
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, glyphTexture->m_fbo);
GLuint tmp_texture;
glGenTextures(1, &tmp_texture);
@@ -196,7 +201,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glBindTexture(GL_TEXTURE_2D, m_texture);
+ glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
@@ -211,12 +216,18 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
pex->updateClipScissorTest();
}
-void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
+void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
{
- if (ctx->d_ptr->workaround_brokenFBOReadBack) {
- QImageTextureGlyphCache::fillTexture(c, glyph);
+ if (ctx == 0) {
+ qWarning("QGLTextureGlyphCache::fillTexture: Called with no context");
+ return;
+ }
- glBindTexture(GL_TEXTURE_2D, m_texture);
+ QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
+ if (pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) {
+ QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
+
+ glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
const QImage &texture = image();
const uchar *bits = texture.constBits();
bits += c.y * texture.bytesPerLine() + c.x;
@@ -224,11 +235,10 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits);
bits += texture.bytesPerLine();
}
-
return;
}
- QImage mask = textureMapForGlyph(glyph);
+ QImage mask = textureMapForGlyph(glyph, subPixelPosition);
const int maskWidth = mask.width();
const int maskHeight = mask.height();
@@ -254,7 +264,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
}
}
- glBindTexture(GL_TEXTURE_2D, m_texture);
+ glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
if (mask.format() == QImage::Format_RGB32) {
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
} else {
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 6bcd655526..345684d576 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -57,64 +57,85 @@
#include <private/qgl_p.h>
#include <qglshaderprogram.h>
+// #define QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
QT_BEGIN_NAMESPACE
class QGL2PaintEngineExPrivate;
-class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QImageTextureGlyphCache
+struct QGLGlyphTexture
+{
+ QGLGlyphTexture(const QGLContext *ctx)
+ : m_width(0)
+ , m_height(0)
+ {
+ if (ctx && !ctx->d_ptr->workaround_brokenFBOReadBack)
+ glGenFramebuffers(1, &m_fbo);
+
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug(" -> QGLGlyphTexture() %p for context %p.", this, ctx);
+#endif
+ }
+
+ ~QGLGlyphTexture() {
+ const QGLContext *ctx = QGLContext::currentContext();
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug("~QGLGlyphTexture() %p for context %p.", this, ctx);
+#endif
+ // At this point, the context group is made current, so it's safe to
+ // release resources without a makeCurrent() call
+ if (ctx) {
+ if (!ctx->d_ptr->workaround_brokenFBOReadBack)
+ glDeleteFramebuffers(1, &m_fbo);
+ if (m_width || m_height)
+ glDeleteTextures(1, &m_texture);
+ }
+ }
+
+ GLuint m_texture;
+ GLuint m_fbo;
+ int m_width;
+ int m_height;
+};
+
+class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QImageTextureGlyphCache
{
- Q_OBJECT
public:
- QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix);
+ QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix);
~QGLTextureGlyphCache();
virtual void createTextureData(int width, int height);
virtual void resizeTextureData(int width, int height);
- virtual void fillTexture(const Coord &c, glyph_t glyph);
+ virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition);
virtual int glyphPadding() const;
- inline GLuint texture() const { return m_texture; }
+ inline GLuint texture() const {
+ QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ return glyphTexture ? glyphTexture->m_texture : 0;
+ }
- inline int width() const { return m_width; }
- inline int height() const { return m_height; }
+ inline int width() const {
+ QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ return glyphTexture ? glyphTexture->m_width : 0;
+ }
+ inline int height() const {
+ QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ return glyphTexture ? glyphTexture->m_height : 0;
+ }
inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; }
-
-public Q_SLOTS:
- void contextDestroyed(const QGLContext *context) {
- if (context == ctx) {
- const QGLContext *nextCtx = qt_gl_transfer_context(ctx);
- if (!nextCtx) {
- // the context may not be current, so we cannot directly
- // destroy the fbo and texture here, but since the context
- // is about to be destroyed, the GL server will do the
- // clean up for us anyway
- m_fbo = 0;
- m_texture = 0;
- ctx = 0;
- } else {
- // since the context holding the texture is shared, and
- // about to be destroyed, we have to transfer ownership
- // of the texture to one of the share contexts
- ctx = const_cast<QGLContext *>(nextCtx);
- }
- }
- }
+ void setContext(const QGLContext *context);
+ inline const QGLContext *context() const { return ctx; }
private:
- QGLContext *ctx;
+ QGLContextGroupResource<QGLGlyphTexture> m_textureResource;
+ const QGLContext *ctx;
QGL2PaintEngineExPrivate *pex;
-
- GLuint m_texture;
- GLuint m_fbo;
-
- int m_width;
- int m_height;
-
- QGLShaderProgram *m_program;
};
QT_END_NAMESPACE
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 0e82467a0a..c7ca4bc7d6 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -20,6 +20,7 @@ contains(QT_CONFIG, egl):CONFIG += egl
HEADERS += qgl.h \
qgl_p.h \
qglcolormap.h \
+ qglfunctions.h \
qglpixelbuffer.h \
qglpixelbuffer_p.h \
qglframebufferobject.h \
@@ -29,8 +30,9 @@ HEADERS += qgl.h \
qglbuffer.h \
-SOURCES += qgl.cpp \
+SOURCES += qgl.cpp \
qglcolormap.cpp \
+ qglfunctions.cpp \
qglpixelbuffer.cpp \
qglframebufferobject.cpp \
qglextensions.cpp \
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 15070d475c..d9b094e109 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -94,6 +94,8 @@
#include <qmutex.h>
+// #define QT_GL_CONTEXT_RESOURCE_DEBUG
+
QT_BEGIN_NAMESPACE
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
@@ -105,6 +107,10 @@ extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
#endif
struct QGLThreadContext {
+ ~QGLThreadContext() {
+ if (context)
+ context->doneCurrent();
+ }
QGLContext *context;
};
@@ -1657,6 +1663,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
#if defined(Q_WS_WIN)
dc = 0;
win = 0;
+ threadId = 0;
pixelFormatId = 0;
cmap = 0;
hbitmap = 0;
@@ -2062,6 +2069,9 @@ QGLContext::~QGLContext()
// remove any textures cached in this context
QGLTextureCache::instance()->removeContextTextures(this);
+ // clean up resources specific to this context
+ d_ptr->cleanup();
+ // clean up resources belonging to this context's group
d_ptr->group->cleanupResources(this);
QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
@@ -2070,6 +2080,10 @@ QGLContext::~QGLContext()
void QGLContextPrivate::cleanup()
{
+ QHash<QGLContextResourceBase *, void *>::ConstIterator it;
+ for (it = m_resources.begin(); it != m_resources.end(); ++it)
+ it.key()->freeResource(it.value());
+ m_resources.clear();
}
#define ctx q_ptr
@@ -2129,20 +2143,10 @@ void QGLContextPrivate::swapRegion(const QRegion *)
GLuint QGLContext::bindTexture(const QString &fileName)
{
- Q_D(QGLContext);
- QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
- QGLDDSCache::const_iterator it = dds_cache->constFind(fileName);
- if (it != dds_cache->constEnd()) {
- glBindTexture(GL_TEXTURE_2D, it.value());
- return it.value();
- }
-
QGLTexture texture(this);
QSize size = texture.bindCompressedTexture(fileName);
if (!size.isValid())
return 0;
-
- dds_cache->insert(fileName, texture.id);
return texture.id;
}
@@ -2582,7 +2586,8 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
const QX11Info *xinfo = qt_x11Info(paintDevice);
if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType
&& xinfo && xinfo->screen() == pixmap.x11Info().screen()
- && target == GL_TEXTURE_2D)
+ && target == GL_TEXTURE_2D
+ && QApplication::instance()->thread() == QThread::currentThread())
{
if (!workaround_brokenTextureFromPixmap_init) {
workaround_brokenTextureFromPixmap_init = true;
@@ -2803,24 +2808,8 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, Q
*/
void QGLContext::deleteTexture(GLuint id)
{
- Q_D(QGLContext);
-
if (QGLTextureCache::instance()->remove(this, id))
return;
-
- // check the DDS cache if the texture wasn't found in the pixmap/image
- // cache
- QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
- QList<QString> ddsKeys = dds_cache->keys();
- for (int i = 0; i < ddsKeys.size(); ++i) {
- GLuint texture = dds_cache->value(ddsKeys.at(i));
- if (id == texture) {
- dds_cache->remove(ddsKeys.at(i));
- break;
- }
- }
-
- // Finally, actually delete the texture ID
glDeleteTextures(1, &id);
}
@@ -3617,12 +3606,90 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
\section1 Threading
- It is possible to render into a QGLWidget from another thread, but it
- requires that all access to the GL context is safe guarded. The Qt GUI
- thread will try to use the context in resizeEvent and paintEvent, so in
- order for threaded rendering using a GL widget to work, these functions
- need to be intercepted in the GUI thread and handled accordingly in the
- application.
+ As of Qt version 4.8, support for doing threaded GL rendering has
+ been improved. There are three scenarios that we currently support:
+ \list
+ \o 1. Buffer swapping in a thread.
+
+ Swapping buffers in a double buffered context may be a
+ synchronous, locking call that may be a costly operation in some
+ GL implementations. Especially so on embedded devices. It's not
+ optimal to have the CPU idling while the GPU is doing a buffer
+ swap. In those cases it is possible to do the rendering in the
+ main thread and do the actual buffer swap in a separate
+ thread. This can be done with the following steps:
+
+ 1. Call doneCurrent() in the main thread when the rendering is
+ finished.
+
+ 2. Notify the swapping thread that it can grab the context.
+
+ 3. Make the rendering context current in the swapping thread with
+ makeCurrent() and then call swapBuffers().
+
+ 4. Call doneCurrent() in the swapping thread and notify the main
+ thread that swapping is done.
+
+ Doing this will free up the main thread so that it can continue
+ with, for example, handling UI events or network requests. Even if
+ there is a context swap involved, it may be preferable compared to
+ having the main thread wait while the GPU finishes the swap
+ operation. Note that this is highly implementation dependent.
+
+ \o 2. Texture uploading in a thread.
+
+ Doing texture uploads in a thread may be very useful for
+ applications handling large amounts of images that needs to be
+ displayed, like for instance a photo gallery application. This is
+ supported in Qt through the existing bindTexture() API. A simple
+ way of doing this is to create two sharing QGLWidgets. One is made
+ current in the main GUI thread, while the other is made current in
+ the texture upload thread. The widget in the uploading thread is
+ never shown, it is only used for sharing textures with the main
+ thread. For each texture that is bound via bindTexture(), notify
+ the main thread so that it can start using the texture.
+
+ \o 3. Using QPainter to draw into a QGLWidget in a thread.
+
+ In Qt 4.8, it is possible to draw into a QGLWidget using a
+ QPainter in a separate thread. Note that this is also possible for
+ QGLPixelBuffers and QGLFramebufferObjects. Since this is only
+ supported in the GL 2 paint engine, OpenGL 2.0 or OpenGL ES 2.0 is
+ required.
+
+ QGLWidgets can only be created in the main GUI thread. This means
+ a call to doneCurrent() is necessary to release the GL context
+ from the main thread, before the widget can be drawn into by
+ another thread. Also, the main GUI thread will dispatch resize and
+ paint events to a QGLWidget when the widget is resized, or parts
+ of it becomes exposed or needs redrawing. It is therefore
+ necessary to handle those events because the default
+ implementations inside QGLWidget will try to make the QGLWidget's
+ context current, which again will interfere with any threads
+ rendering into the widget. Reimplement QGLWidget::paintEvent() and
+ QGLWidget::resizeEvent() to notify the rendering thread that a
+ resize or update is necessary, and be careful not to call the base
+ class implementation. If you are rendering an animation, it might
+ not be necessary to handle the paint event at all since the
+ rendering thread is doing regular updates. Then it would be enough
+ to reimplement QGLWidget::paintEvent() to do nothing.
+
+ \endlist
+
+ As a general rule when doing threaded rendering: be aware that
+ binding and releasing contexts in different threads have to be
+ synchronized by the user. A GL rendering context can only be
+ current in one thread at any time. If you try to open a QPainter
+ on a QGLWidget and the widget's rendering context is current in
+ another thread, it will fail.
+
+ Note that under X11 it is necessary to set the
+ Qt::AA_X11InitThreads application attribute to make the X11
+ library and GLX calls thread safe, otherwise the above scenarios
+ will fail.
+
+ In addition to this, rendering using raw GL calls in a separate
+ thread is supported.
\e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other
countries.}
@@ -4138,13 +4205,7 @@ bool QGLWidget::event(QEvent *e)
}
#if defined(Q_WS_X11)
- // prevents X errors on some systems, where we get a flush to a
- // hidden widget
- if (e->type() == QEvent::Hide) {
- makeCurrent();
- glFinish();
- doneCurrent();
- } else if (e->type() == QEvent::ParentChange) {
+ if (e->type() == QEvent::ParentChange) {
// if we've reparented a window that has the current context
// bound, we need to rebind that context to the new window id
if (d->glcx == QGLContext::currentContext())
@@ -5146,24 +5207,24 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM
#endif
#ifndef QT_OPENGL_ES_1
-Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine)
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_gl_2_engine)
#endif
#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine)
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_gl_engine)
#endif
Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
{
#if defined(QT_OPENGL_ES_1)
- return qt_gl_engine();
+ return qt_gl_engine()->engine();
#elif defined(QT_OPENGL_ES_2)
- return qt_gl_2_engine();
+ return qt_gl_2_engine()->engine();
#else
if (qt_gl_preferGL2Engine())
- return qt_gl_2_engine();
+ return qt_gl_2_engine()->engine();
else
- return qt_gl_engine();
+ return qt_gl_engine()->engine();
#endif
}
@@ -5433,13 +5494,23 @@ void QGLContextGroup::removeShare(const QGLContext *context) {
group->m_shares.clear();
}
-QGLContextResource::QGLContextResource(FreeFunc f)
- : free(f), active(0)
+QGLContextGroupResourceBase::QGLContextGroupResourceBase()
+ : active(0)
{
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Creating context group resource object %p.", this);
+#endif
}
-QGLContextResource::~QGLContextResource()
+QGLContextGroupResourceBase::~QGLContextGroupResourceBase()
{
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Deleting context group resource %p. Group size: %d.", this, m_groups.size());
+#endif
+ for (int i = 0; i < m_groups.size(); ++i) {
+ m_groups.at(i)->m_resources.remove(this);
+ active.deref();
+ }
#ifndef QT_NO_DEBUG
if (active != 0) {
qWarning("QtOpenGL: Resources are still available at program shutdown.\n"
@@ -5449,37 +5520,47 @@ QGLContextResource::~QGLContextResource()
#endif
}
-void QGLContextResource::insert(const QGLContext *key, void *value)
+void QGLContextGroupResourceBase::insert(const QGLContext *context, void *value)
{
- QGLContextGroup *group = QGLContextPrivate::contextGroup(key);
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Inserting context group resource %p for context %p, managed by %p.", value, context, this);
+#endif
+ QGLContextGroup *group = QGLContextPrivate::contextGroup(context);
Q_ASSERT(!group->m_resources.contains(this));
group->m_resources.insert(this, value);
+ m_groups.append(group);
active.ref();
}
-void *QGLContextResource::value(const QGLContext *key)
+void *QGLContextGroupResourceBase::value(const QGLContext *context)
{
- QGLContextGroup *group = QGLContextPrivate::contextGroup(key);
+ QGLContextGroup *group = QGLContextPrivate::contextGroup(context);
return group->m_resources.value(this, 0);
}
-void QGLContextResource::cleanup(const QGLContext *ctx, void *value)
+void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx, void *value)
{
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Cleaning up context group resource %p, for context %p in thread %p.", this, ctx, QThread::currentThread());
+#endif
QGLShareContextScope scope(ctx);
- free(value);
+ freeResource(value);
active.deref();
+
+ QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
+ m_groups.removeOne(group);
}
-void QGLContextGroup::cleanupResources(const QGLContext *ctx)
+void QGLContextGroup::cleanupResources(const QGLContext *context)
{
// If there are still shares, then no cleanup to be done yet.
if (m_shares.size() > 1)
return;
// Iterate over all resources and free each in turn.
- QHash<QGLContextResource *, void *>::ConstIterator it;
+ QHash<QGLContextGroupResourceBase *, void *>::ConstIterator it;
for (it = m_resources.begin(); it != m_resources.end(); ++it)
- it.key()->cleanup(ctx, it.value());
+ it.key()->cleanup(context, it.value());
}
QGLSharedResourceGuard::~QGLSharedResourceGuard()
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index f85cad56cc..2ac4cb6b9a 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -56,7 +56,6 @@ QT_BEGIN_HEADER
#if defined(Q_WS_MAC)
# include <OpenGL/gl.h>
-# include <OpenGL/glu.h>
#elif defined(QT_OPENGL_ES_1)
# include <GLES/gl.h>
#ifndef GL_DOUBLE
@@ -75,9 +74,6 @@ typedef GLfloat GLdouble;
#endif
#else
# include <GL/gl.h>
-# ifndef QT_LINUXBASE
-# include <GL/glu.h>
-# endif
#endif
QT_BEGIN_NAMESPACE
@@ -424,6 +420,7 @@ private:
friend class QGLPixmapData;
friend class QGLPixmapFilterBase;
friend class QGLTextureGlyphCache;
+ friend struct QGLGlyphTexture;
friend class QGLContextGroup;
friend class QGLSharedResourceGuard;
friend class QGLPixmapBlurFilter;
@@ -443,6 +440,7 @@ private:
friend class QGLWidgetGLPaintDevice;
friend class QX11GLPixmapData;
friend class QX11GLSharedContexts;
+ friend class QGLContextResourceBase;
private:
Q_DISABLE_COPY(QGLContext)
};
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 623eeafa9b..78f888ab27 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -217,11 +217,9 @@ public:
#endif
};
-class QGLContextResource;
+class QGLContextGroupResourceBase;
class QGLSharedResourceGuard;
-typedef QHash<QString, GLuint> QGLDDSCache;
-
// QGLContextPrivate has the responsibility of creating context groups.
// QGLContextPrivate maintains the reference counter and destroys
// context groups when needed.
@@ -240,22 +238,22 @@ public:
static void addShare(const QGLContext *context, const QGLContext *share);
static void removeShare(const QGLContext *context);
+
private:
QGLContextGroup(const QGLContext *context);
QGLExtensionFuncs m_extensionFuncs;
const QGLContext *m_context; // context group's representative
QList<const QGLContext *> m_shares;
- QHash<QGLContextResource *, void *> m_resources;
+ QHash<QGLContextGroupResourceBase *, void *> m_resources;
QGLSharedResourceGuard *m_guards; // double-linked list of active guards.
QAtomicInt m_refs;
- QGLDDSCache m_dds_cache;
void cleanupResources(const QGLContext *ctx);
friend class QGLContext;
friend class QGLContextPrivate;
- friend class QGLContextResource;
+ friend class QGLContextGroupResourceBase;
};
// Get the context that resources for "ctx" will transfer to once
@@ -321,6 +319,8 @@ class QGLTexture;
// all the GL2 engine uses:
#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
+class QGLContextResourceBase;
+
class QGLContextPrivate
{
Q_DECLARE_PUBLIC(QGLContext)
@@ -356,6 +356,7 @@ public:
QGLCmap* cmap;
HBITMAP hbitmap;
HDC hbitmap_hdc;
+ Qt::HANDLE threadId;
#endif
#ifndef QT_NO_EGL
uint ownsEglContext : 1;
@@ -416,6 +417,7 @@ public:
GLuint current_fbo;
GLuint default_fbo;
QPaintEngine *active_engine;
+ QHash<QGLContextResourceBase *, void *> m_resources;
bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
@@ -426,7 +428,7 @@ public:
#endif
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
- static QGLExtensionFuncs qt_extensionFuncs;
+ static Q_OPENGL_EXPORT QGLExtensionFuncs qt_extensionFuncs;
static Q_OPENGL_EXPORT QGLExtensionFuncs& extensionFuncs(const QGLContext *);
#endif
@@ -624,24 +626,130 @@ inline GLenum qt_gl_preferredTextureTarget()
#endif
}
-// One resource per group of shared contexts.
-class Q_OPENGL_EXPORT QGLContextResource
+/*
+ Base for resources that are shared in a context group.
+*/
+class Q_OPENGL_EXPORT QGLContextGroupResourceBase
{
public:
- typedef void (*FreeFunc)(void *);
- QGLContextResource(FreeFunc f);
- ~QGLContextResource();
- // Set resource 'value' for 'key' and all its shared contexts.
- void insert(const QGLContext *key, void *value);
- // Return resource for 'key' or a shared context.
- void *value(const QGLContext *key);
- // Cleanup 'value' in response to a context group being destroyed.
- void cleanup(const QGLContext *ctx, void *value);
+ QGLContextGroupResourceBase();
+ virtual ~QGLContextGroupResourceBase();
+ void insert(const QGLContext *context, void *value);
+ void *value(const QGLContext *context);
+ void cleanup(const QGLContext *context, void *value);
+ virtual void freeResource(void *value) = 0;
+
+protected:
+ QList<QGLContextGroup *> m_groups;
+
private:
- FreeFunc free;
QAtomicInt active;
};
+/*
+ The QGLContextGroupResource template is used to manage a resource
+ for a group of sharing GL contexts. When the last context in the
+ group is destroyed, or when the QGLContextGroupResource object
+ itself is destroyed (implies potential context switches), the
+ resource will be freed.
+
+ The class used as the template class type needs to have a
+ constructor with the following signature:
+ T(const QGLContext *);
+*/
+template <class T>
+class QGLContextGroupResource : public QGLContextGroupResourceBase
+{
+public:
+ ~QGLContextGroupResource() {
+ for (int i = 0; i < m_groups.size(); ++i) {
+ const QGLContext *context = m_groups.at(i)->context();
+ T *resource = reinterpret_cast<T *>(QGLContextGroupResourceBase::value(context));
+ if (resource) {
+ QGLShareContextScope scope(context);
+ delete resource;
+ }
+ }
+ }
+
+ T *value(const QGLContext *context) {
+ T *resource = reinterpret_cast<T *>(QGLContextGroupResourceBase::value(context));
+ if (!resource) {
+ resource = new T(context);
+ insert(context, resource);
+ }
+ return resource;
+ }
+
+protected:
+ void freeResource(void *resource) {
+ delete reinterpret_cast<T *>(resource);
+ }
+};
+
+/*
+ Base for resources that are context specific.
+*/
+class Q_OPENGL_EXPORT QGLContextResourceBase
+{
+public:
+ virtual ~QGLContextResourceBase() {
+ for (int i = 0; i < m_contexts.size(); ++i)
+ m_contexts.at(i)->d_ptr->m_resources.remove(this);
+ }
+
+ void insert(const QGLContext *context, void *value) {
+ context->d_ptr->m_resources.insert(this, value);
+ }
+
+ void *value(const QGLContext *context) {
+ return context->d_ptr->m_resources.value(this, 0);
+ }
+ virtual void freeResource(void *value) = 0;
+
+protected:
+ QList<const QGLContext *> m_contexts;
+};
+
+/*
+ The QGLContextResource template is used to manage a resource for a
+ single GL context. Just before the context is destroyed (while it's
+ still the current context), or when the QGLContextResource object
+ itself is destroyed (implies potential context switches), the
+ resource will be freed. The class used as the template class type
+ needs to have a constructor with the following signature: T(const
+ QGLContext *);
+*/
+template <class T>
+class QGLContextResource : public QGLContextResourceBase
+{
+public:
+ ~QGLContextResource() {
+ for (int i = 0; i < m_contexts.size(); ++i) {
+ const QGLContext *context = m_contexts.at(i);
+ T *resource = reinterpret_cast<T *>(QGLContextResourceBase::value(context));
+ if (resource) {
+ QGLShareContextScope scope(context);
+ delete resource;
+ }
+ }
+ }
+
+ T *value(const QGLContext *context) {
+ T *resource = reinterpret_cast<T *>(QGLContextResourceBase::value(context));
+ if (!resource) {
+ resource = new T(context);
+ insert(context, resource);
+ }
+ return resource;
+ }
+
+protected:
+ void freeResource(void *resource) {
+ delete reinterpret_cast<T *>(resource);
+ }
+};
+
// Put a guard around a GL object identifier and its context.
// When the context goes away, a shared context will be used
// in its place. If there are no more shared contexts, then
@@ -731,6 +839,24 @@ private:
int gl_extensions_length;
};
+
+// this is a class that wraps a QThreadStorage object for storing
+// thread local instances of the GL 1 and GL 2 paint engines
+
+template <class T>
+class QGLEngineThreadStorage
+{
+public:
+ QPaintEngine *engine() {
+ QPaintEngine *&localEngine = storage.localData();
+ if (!localEngine)
+ localEngine = new T;
+ return localEngine;
+ }
+
+private:
+ QThreadStorage<QPaintEngine *> storage;
+};
QT_END_NAMESPACE
#endif // QGL_P_H
diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp
index 8eb61772d0..5f7d4e2c77 100644
--- a/src/opengl/qgl_win.cpp
+++ b/src/opengl/qgl_win.cpp
@@ -1261,6 +1261,7 @@ void QGLContext::reset()
}
d->dc = 0;
d->win = 0;
+ d->threadId = 0;
d->pixelFormatId = 0;
d->sharing = false;
d->valid = false;
@@ -1283,8 +1284,9 @@ void QGLContext::makeCurrent()
if (d->rc == wglGetCurrentContext() || !d->valid) // already current
return;
- if (d->win) {
+ if (d->win && (!d->dc || d->threadId != QThread::currentThreadId())) {
d->dc = GetDC(d->win);
+ d->threadId = QThread::currentThreadId();
if (!d->dc) {
qwglError("QGLContext::makeCurrent()", "GetDC()");
return;
@@ -1322,6 +1324,7 @@ void QGLContext::doneCurrent()
if (d->win && d->dc) {
ReleaseDC(d->win, d->dc);
d->dc = 0;
+ d->threadId = 0;
}
}
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index 9d28de0b02..1f7e60a3a9 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -97,7 +97,6 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
XVisualInfo visualInfo;
XVisualInfo *vi;
int numVisuals;
- EGLint id = 0;
visualInfo.visualid = QEgl::getCompatibleVisualId(config);
vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals);
@@ -346,7 +345,7 @@ void QGLWidgetPrivate::recreateEglSurface()
// old surface before re-creating a new one. Note: This should not be the case as the
// surface should be deleted before the old window id.
if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) {
- qWarning("EGL surface for deleted window %x was not destroyed", eglSurfaceWindowId);
+ qWarning("EGL surface for deleted window %lx was not destroyed", eglSurfaceWindowId);
glcx->d_func()->destroyEglSurfaceForDevice();
}
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index 6259cca09e..6d7449d7a4 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -872,10 +872,10 @@ struct QGLExtensionFuncs
#endif
extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
-bool qt_resolve_buffer_extensions(QGLContext *ctx);
+bool Q_OPENGL_EXPORT qt_resolve_buffer_extensions(QGLContext *ctx);
bool qt_resolve_version_1_3_functions(QGLContext *ctx);
-bool qt_resolve_version_2_0_functions(QGLContext *ctx);
+bool Q_OPENGL_EXPORT qt_resolve_version_2_0_functions(QGLContext *ctx);
bool qt_resolve_stencil_face_extension(QGLContext *ctx);
bool qt_resolve_frag_program_extensions(QGLContext *ctx);
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index adbba856ba..cee950aa5e 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -620,6 +620,13 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
as a texture, you first need to copy from it to a regular framebuffer
object using QGLContext::blitFramebuffer().
+ \section Threading
+
+ As of Qt 4.8, it's possible to draw into a QGLFramebufferObject
+ using a QPainter in a separate thread. Note that OpenGL 2.0 or
+ OpenGL ES 2.0 is required for this to work. Also, under X11, it's
+ necessary to set the Qt::AA_X11InitThreads application attribute.
+
\sa {Framebuffer Object Example}
*/
@@ -988,11 +995,11 @@ QImage QGLFramebufferObject::toImage() const
}
#if !defined(QT_OPENGL_ES_1)
-Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine)
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
#endif
#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine)
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
#endif
/*! \reimp */
@@ -1006,7 +1013,7 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const
#if !defined (QT_OPENGL_ES_2)
if (qt_gl_preferGL2Engine()) {
#endif
- QPaintEngine *engine = qt_buffer_2_engine();
+ QPaintEngine *engine = qt_buffer_2_engine()->engine();
if (engine->isActive() && engine->paintDevice() != this) {
d->engine = new QGL2PaintEngineEx;
return d->engine;
@@ -1018,7 +1025,7 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const
#endif
#if !defined(QT_OPENGL_ES_2)
- QPaintEngine *engine = qt_buffer_engine();
+ QPaintEngine *engine = qt_buffer_engine()->engine();
if (engine->isActive() && engine->paintDevice() != this) {
d->engine = new QOpenGLPaintEngine;
return d->engine;
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
new file mode 100644
index 0000000000..8a544c11fa
--- /dev/null
+++ b/src/opengl/qglfunctions.cpp
@@ -0,0 +1,3705 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenGL module 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 "qglfunctions.h"
+#include "qgl_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGLFunctions
+ \brief The QGLFunctions class provides cross-platform access to the OpenGL/ES 2.0 API.
+ \since 4.8
+ \ingroup painting-3D
+
+ OpenGL/ES 2.0 defines a subset of the OpenGL specification that is
+ common across many desktop and embedded OpenGL implementations.
+ However, it can be difficult to use the functions from that subset
+ because they need to be resolved manually on desktop systems.
+
+ QGLFunctions provides a guaranteed API that is available on all
+ OpenGL systems and takes care of function resolution on systems
+ that need it. The recommended way to use QGLFunctions is by
+ direct inheritance:
+
+ \code
+ class MyGLWidget : public QGLWidget, protected QGLFunctions
+ {
+ Q_OBJECT
+ public:
+ MyGLWidget(QWidget *parent = 0) : QGLWidget(parent) {}
+
+ protected:
+ void initializeGL();
+ void paintGL();
+ };
+
+ void MyGLWidget::initializeGL()
+ {
+ initializeGLFunctions();
+ }
+ \endcode
+
+ The \c{paintGL()} function can then use any of the OpenGL/ES 2.0
+ functions without explicit resolution, such as glActiveTexture()
+ in the following example:
+
+ \code
+ void MyGLWidget::paintGL()
+ {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ ...
+ }
+ \endcode
+
+ QGLFunctions can also be used directly for ad-hoc invocation
+ of OpenGL/ES 2.0 functions on all platforms:
+
+ \code
+ QGLFunctions glFuncs(QGLContext::currentContext());
+ glFuncs.glActiveTexture(GL_TEXTURE1);
+ \endcode
+
+ QGLFunctions provides wrappers for all OpenGL/ES 2.0 functions,
+ except those like \c{glDrawArrays()}, \c{glViewport()}, and
+ \c{glBindTexture()} that don't have portability issues.
+
+ Including the header for QGLFunctions will also define all of
+ the OpenGL/ES 2.0 macro constants that are not already defined by
+ the system's OpenGL headers, such as \c{GL_TEXTURE1} above.
+
+ The hasOpenGLFeature() and openGLFeatures() functions can be used
+ to determine if the OpenGL implementation has a major OpenGL/ES 2.0
+ feature. For example, the following checks if non power of two
+ textures are available:
+
+ \code
+ QGLFunctions funcs(QGLContext::currentContext());
+ bool npot = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures);
+ \endcode
+*/
+
+/*!
+ \enum QGLFunctions::OpenGLFeature
+ This enum defines OpenGL/ES 2.0 features that may be optional
+ on other platforms.
+
+ \value Multitexture glActiveTexture() function is available.
+ \value Shaders Shader functions are available.
+ \value Buffers Vertex and index buffer functions are available.
+ \value Framebuffers Framebuffer object functions are available.
+ \value BlendColor glBlendColor() is available.
+ \value BlendEquation glBlendEquation() is available.
+ \value BlendEquationSeparate glBlendEquationSeparate() is available.
+ \value BlendFuncSeparate glBlendFuncSeparate() is available.
+ \value BlendSubtract Blend subtract mode is available.
+ \value CompressedTextures Compressed texture functions are available.
+ \value Multisample glSampleCoverage() function is available.
+ \value StencilSeparate Separate stencil functions are available.
+ \value NPOTTextures Non power of two textures are available.
+*/
+
+// Hidden private fields for additional extension data.
+struct QGLFunctionsPrivateEx : public QGLFunctionsPrivate
+{
+ QGLFunctionsPrivateEx(const QGLContext *context = 0)
+ : QGLFunctionsPrivate(context)
+ , m_features(-1) {}
+
+ int m_features;
+};
+
+#if QT_VERSION >= 0x040800
+Q_GLOBAL_STATIC(QGLContextGroupResource<QGLFunctionsPrivateEx>, qt_gl_functions_resource)
+#else
+static void qt_gl_functions_free(void *data)
+{
+ delete reinterpret_cast<QGLFunctionsPrivateEx *>(data);
+}
+
+Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_gl_functions_resource, (qt_gl_functions_free))
+#endif
+static QGLFunctionsPrivateEx *qt_gl_functions(const QGLContext *context = 0)
+{
+ if (!context)
+ context = QGLContext::currentContext();
+ Q_ASSERT(context);
+ QGLFunctionsPrivateEx *funcs =
+ reinterpret_cast<QGLFunctionsPrivateEx *>
+ (qt_gl_functions_resource()->value(context));
+#if QT_VERSION < 0x040800
+ if (!funcs) {
+ funcs = new QGLFunctionsPrivateEx();
+ qt_gl_functions_resource()->insert(context, funcs);
+ }
+#endif
+ return funcs;
+}
+
+/*!
+ Constructs a default function resolver. The resolver cannot
+ be used until initializeGLFunctions() is called to specify
+ the context.
+
+ \sa initializeGLFunctions()
+*/
+QGLFunctions::QGLFunctions()
+ : d_ptr(0)
+{
+}
+
+/*!
+ Constructs a function resolver for \a context. If \a context
+ is null, then the resolver will be created for the current QGLContext.
+
+ An object constructed in this way can only be used with \a context
+ and other contexts that share with it. Use initializeGLFunctions()
+ to change the object's context association.
+
+ \sa initializeGLFunctions()
+*/
+QGLFunctions::QGLFunctions(const QGLContext *context)
+ : d_ptr(qt_gl_functions(context))
+{
+}
+
+/*!
+ \fn QGLFunctions::~QGLFunctions()
+
+ Destroys this function resolver.
+*/
+
+static int qt_gl_resolve_features()
+{
+#if defined(QT_OPENGL_ES_2)
+ return QGLFunctions::Multitexture |
+ QGLFunctions::Shaders |
+ QGLFunctions::Buffers |
+ QGLFunctions::Framebuffers |
+ QGLFunctions::BlendColor |
+ QGLFunctions::BlendEquation |
+ QGLFunctions::BlendEquationSeparate |
+ QGLFunctions::BlendFuncSeparate |
+ QGLFunctions::BlendSubtract |
+ QGLFunctions::CompressedTextures |
+ QGLFunctions::Multisample |
+ QGLFunctions::StencilSeparate |
+ QGLFunctions::NPOTTextures;
+#elif defined(QT_OPENGL_ES)
+ int features = QGLFunctions::Multitexture |
+ QGLFunctions::Buffers |
+ QGLFunctions::CompressedTextures |
+ QGLFunctions::Multisample;
+ QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+ if (extensions.match("GL_OES_framebuffer_object"))
+ features |= QGLFunctions::Framebuffers;
+ if (extensions.match("GL_OES_blend_equation_separate"))
+ features |= QGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_OES_blend_func_separate"))
+ features |= QGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_OES_blend_subtract"))
+ features |= QGLFunctions::BlendSubtract;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QGLFunctions::NPOTTextures;
+ return features;
+#else
+ int features = 0;
+ QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
+ QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+
+ // Recognize features by extension name.
+ if (extensions.match("GL_ARB_multitexture"))
+ features |= QGLFunctions::Multitexture;
+ if (extensions.match("GL_ARB_shader_objects"))
+ features |= QGLFunctions::Shaders;
+ if (extensions.match("GL_EXT_framebuffer_object") ||
+ extensions.match("GL_ARB_framebuffer_object"))
+ features |= QGLFunctions::Framebuffers;
+ if (extensions.match("GL_EXT_blend_color"))
+ features |= QGLFunctions::BlendColor;
+ if (extensions.match("GL_EXT_blend_equation_separate"))
+ features |= QGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_EXT_blend_func_separate"))
+ features |= QGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_EXT_blend_subtract"))
+ features |= QGLFunctions::BlendSubtract;
+ if (extensions.match("GL_ARB_texture_compression"))
+ features |= QGLFunctions::CompressedTextures;
+ if (extensions.match("GL_ARB_multisample"))
+ features |= QGLFunctions::Multisample;
+ if (extensions.match("GL_ARB_texture_non_power_of_two"))
+ features |= QGLFunctions::NPOTTextures;
+
+ // Recognize features by minimum OpenGL version.
+ if (versions & QGLFormat::OpenGL_Version_1_2) {
+ features |= QGLFunctions::BlendColor |
+ QGLFunctions::BlendEquation;
+ }
+ if (versions & QGLFormat::OpenGL_Version_1_3) {
+ features |= QGLFunctions::Multitexture |
+ QGLFunctions::CompressedTextures |
+ QGLFunctions::Multisample;
+ }
+ if (versions & QGLFormat::OpenGL_Version_1_4)
+ features |= QGLFunctions::BlendFuncSeparate;
+ if (versions & QGLFormat::OpenGL_Version_1_5)
+ features |= QGLFunctions::Buffers;
+ if (versions & QGLFormat::OpenGL_Version_2_0) {
+ features |= QGLFunctions::Shaders |
+ QGLFunctions::StencilSeparate |
+ QGLFunctions::BlendEquationSeparate |
+ QGLFunctions::NPOTTextures;
+ }
+ return features;
+#endif
+}
+
+/*!
+ Returns the set of features that are present on this system's
+ OpenGL implementation.
+
+ It is assumed that the QGLContext associated with this function
+ resolver is current.
+
+ \sa hasOpenGLFeature()
+*/
+QGLFunctions::OpenGLFeatures QGLFunctions::openGLFeatures() const
+{
+ QGLFunctionsPrivateEx *d = static_cast<QGLFunctionsPrivateEx *>(d_ptr);
+ if (!d)
+ return 0;
+ if (d->m_features == -1)
+ d->m_features = qt_gl_resolve_features();
+ return QGLFunctions::OpenGLFeatures(d->m_features);
+}
+
+/*!
+ Returns true if \a feature is present on this system's OpenGL
+ implementation; false otherwise.
+
+ It is assumed that the QGLContext associated with this function
+ resolver is current.
+
+ \sa openGLFeatures()
+*/
+bool QGLFunctions::hasOpenGLFeature(QGLFunctions::OpenGLFeature feature) const
+{
+ QGLFunctionsPrivateEx *d = static_cast<QGLFunctionsPrivateEx *>(d_ptr);
+ if (!d)
+ return false;
+ if (d->m_features == -1)
+ d->m_features = qt_gl_resolve_features();
+ return (d->m_features & int(feature)) != 0;
+}
+
+/*!
+ Initializes GL function resolution for \a context. If \a context
+ is null, then the current QGLContext will be used.
+
+ After calling this function, the QGLFunctions object can only be
+ used with \a context and other contexts that share with it.
+ Call initializeGLFunctions() again to change the object's context
+ association.
+*/
+void QGLFunctions::initializeGLFunctions(const QGLContext *context)
+{
+ d_ptr = qt_gl_functions(context);
+}
+
+/*!
+ \fn void QGLFunctions::glActiveTexture(GLenum texture)
+
+ Convenience function that calls glActiveTexture(\a texture).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glActiveTexture.xml}{glActiveTexture()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glAttachShader(GLuint program, GLuint shader)
+
+ Convenience function that calls glAttachShader(\a program, \a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glAttachShader.xml}{glAttachShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glBindAttribLocation(GLuint program, GLuint index, const char* name)
+
+ Convenience function that calls glBindAttribLocation(\a program, \a index, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindAttribLocation.xml}{glBindAttribLocation()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glBindBuffer(GLenum target, GLuint buffer)
+
+ Convenience function that calls glBindBuffer(\a target, \a buffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindBuffer.xml}{glBindBuffer()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBindFramebuffer(GLenum target, GLuint framebuffer)
+
+ Convenience function that calls glBindFramebuffer(\a target, \a framebuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindFramebuffer.xml}{glBindFramebuffer()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+
+ Convenience function that calls glBindRenderbuffer(\a target, \a renderbuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindRenderbuffer.xml}{glBindRenderbuffer()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+
+ Convenience function that calls glBlendColor(\a red, \a green, \a blue, \a alpha).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendColor.xml}{glBlendColor()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBlendEquation(GLenum mode)
+
+ Convenience function that calls glBlendEquation(\a mode).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquation.xml}{glBlendEquation()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+
+ Convenience function that calls glBlendEquationSeparate(\a modeRGB, \a modeAlpha).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquationSeparate.xml}{glBlendEquationSeparate()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+
+ Convenience function that calls glBlendFuncSeparate(\a srcRGB, \a dstRGB, \a srcAlpha, \a dstAlpha).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendFuncSeparate.xml}{glBlendFuncSeparate()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
+
+ Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBufferData.xml}{glBufferData()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
+
+ Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBufferSubData.xml}{glBufferSubData()}.
+*/
+
+/*!
+ \fn GLenum QGLFunctions::glCheckFramebufferStatus(GLenum target)
+
+ Convenience function that calls glCheckFramebufferStatus(\a target).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCheckFramebufferStatus.xml}{glCheckFramebufferStatus()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glClearDepthf(GLclampf depth)
+
+ Convenience function that calls glClearDepth(\a depth) on
+ desktop OpenGL systems and glClearDepthf(\a depth) on
+ embedded OpenGL/ES systems.
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glClearDepthf.xml}{glClearDepthf()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glCompileShader(GLuint shader)
+
+ Convenience function that calls glCompileShader(\a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCompileShader.xml}{glCompileShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+
+ Convenience function that calls glCompressedTexImage2D(\a target, \a level, \a internalformat, \a width, \a height, \a border, \a imageSize, \a data).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexImage2D.xml}{glCompressedTexImage2D()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+
+ Convenience function that calls glCompressedTexSubImage2D(\a target, \a level, \a xoffset, \a yoffset, \a width, \a height, \a format, \a imageSize, \a data).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexSubImage2D.xml}{glCompressedTexSubImage2D()}.
+*/
+
+/*!
+ \fn GLuint QGLFunctions::glCreateProgram()
+
+ Convenience function that calls glCreateProgram().
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCreateProgram.xml}{glCreateProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLuint QGLFunctions::glCreateShader(GLenum type)
+
+ Convenience function that calls glCreateShader(\a type).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCreateShader.xml}{glCreateShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers)
+
+ Convenience function that calls glDeleteBuffers(\a n, \a buffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteBuffers.xml}{glDeleteBuffers()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+
+ Convenience function that calls glDeleteFramebuffers(\a n, \a framebuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteFramebuffers.xml}{glDeleteFramebuffers()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glDeleteProgram(GLuint program)
+
+ Convenience function that calls glDeleteProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteProgram.xml}{glDeleteProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+
+ Convenience function that calls glDeleteRenderbuffers(\a n, \a renderbuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteRenderbuffers.xml}{glDeleteRenderbuffers()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glDeleteShader(GLuint shader)
+
+ Convenience function that calls glDeleteShader(\a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteShader.xml}{glDeleteShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glDepthRangef(GLclampf zNear, GLclampf zFar)
+
+ Convenience function that calls glDepthRange(\a zNear, \a zFar) on
+ desktop OpenGL systems and glDepthRangef(\a zNear, \a zFar) on
+ embedded OpenGL/ES systems.
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDepthRangef.xml}{glDepthRangef()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glDetachShader(GLuint program, GLuint shader)
+
+ Convenience function that calls glDetachShader(\a program, \a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDetachShader.xml}{glDetachShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glDisableVertexAttribArray(GLuint index)
+
+ Convenience function that calls glDisableVertexAttribArray(\a index).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDisableVertexAttribArray.xml}{glDisableVertexAttribArray()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glEnableVertexAttribArray(GLuint index)
+
+ Convenience function that calls glEnableVertexAttribArray(\a index).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glEnableVertexAttribArray.xml}{glEnableVertexAttribArray()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+
+ Convenience function that calls glFramebufferRenderbuffer(\a target, \a attachment, \a renderbuffertarget, \a renderbuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferRenderbuffer.xml}{glFramebufferRenderbuffer()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+
+ Convenience function that calls glFramebufferTexture2D(\a target, \a attachment, \a textarget, \a texture, \a level).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferTexture2D.xml}{glFramebufferTexture2D()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers)
+
+ Convenience function that calls glGenBuffers(\a n, \a buffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenBuffers.xml}{glGenBuffers()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGenerateMipmap(GLenum target)
+
+ Convenience function that calls glGenerateMipmap(\a target).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenerateMipmap.xml}{glGenerateMipmap()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+
+ Convenience function that calls glGenFramebuffers(\a n, \a framebuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenFramebuffers.xml}{glGenFramebuffers()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+
+ Convenience function that calls glGenRenderbuffers(\a n, \a renderbuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenRenderbuffers.xml}{glGenRenderbuffers()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+
+ Convenience function that calls glGetActiveAttrib(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveAttrib.xml}{glGetActiveAttrib()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+
+ Convenience function that calls glGetActiveUniform(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveUniform.xml}{glGetActiveUniform()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+
+ Convenience function that calls glGetAttachedShaders(\a program, \a maxcount, \a count, \a shaders).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttachedShaders.xml}{glGetAttachedShaders()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn int QGLFunctions::glGetAttribLocation(GLuint program, const char* name)
+
+ Convenience function that calls glGetAttribLocation(\a program, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttribLocation.xml}{glGetAttribLocation()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetBufferParameteriv(\a target, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetBufferParameteriv.xml}{glGetBufferParameteriv()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetFramebufferAttachmentParameteriv(\a target, \a attachment, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetFramebufferAttachmentParameteriv.xml}{glGetFramebufferAttachmentParameteriv()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetProgramiv(\a program, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramiv.xml}{glGetProgramiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+
+ Convenience function that calls glGetProgramInfoLog(\a program, \a bufsize, \a length, \a infolog).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramInfoLog.xml}{glGetProgramInfoLog()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetRenderbufferParameteriv(\a target, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetRenderbufferParameteriv.xml}{glGetRenderbufferParameteriv()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetShaderiv(\a shader, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderiv.xml}{glGetShaderiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+
+ Convenience function that calls glGetShaderInfoLog(\a shader, \a bufsize, \a length, \a infolog).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderInfoLog.xml}{glGetShaderInfoLog()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+
+ Convenience function that calls glGetShaderPrecisionFormat(\a shadertype, \a precisiontype, \a range, \a precision).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderPrecisionFormat.xml}{glGetShaderPrecisionFormat()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+
+ Convenience function that calls glGetShaderSource(\a shader, \a bufsize, \a length, \a source).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderSource.xml}{glGetShaderSource()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+
+ Convenience function that calls glGetUniformfv(\a program, \a location, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformfv.xml}{glGetUniformfv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetUniformiv(GLuint program, GLint location, GLint* params)
+
+ Convenience function that calls glGetUniformiv(\a program, \a location, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformiv.xml}{glGetUniformiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn int QGLFunctions::glGetUniformLocation(GLuint program, const char* name)
+
+ Convenience function that calls glGetUniformLocation(\a program, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformLocation.xml}{glGetUniformLocation()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+
+ Convenience function that calls glGetVertexAttribfv(\a index, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribfv.xml}{glGetVertexAttribfv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetVertexAttribiv(\a index, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribiv.xml}{glGetVertexAttribiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
+
+ Convenience function that calls glGetVertexAttribPointerv(\a index, \a pname, \a pointer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribPointerv.xml}{glGetVertexAttribPointerv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLboolean QGLFunctions::glIsBuffer(GLuint buffer)
+
+ Convenience function that calls glIsBuffer(\a buffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsBuffer.xml}{glIsBuffer()}.
+*/
+
+/*!
+ \fn GLboolean QGLFunctions::glIsFramebuffer(GLuint framebuffer)
+
+ Convenience function that calls glIsFramebuffer(\a framebuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsFramebuffer.xml}{glIsFramebuffer()}.
+*/
+
+/*!
+ \fn GLboolean QGLFunctions::glIsProgram(GLuint program)
+
+ Convenience function that calls glIsProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsProgram.xml}{glIsProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLboolean QGLFunctions::glIsRenderbuffer(GLuint renderbuffer)
+
+ Convenience function that calls glIsRenderbuffer(\a renderbuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsRenderbuffer.xml}{glIsRenderbuffer()}.
+*/
+
+/*!
+ \fn GLboolean QGLFunctions::glIsShader(GLuint shader)
+
+ Convenience function that calls glIsShader(\a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsShader.xml}{glIsShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glLinkProgram(GLuint program)
+
+ Convenience function that calls glLinkProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glLinkProgram.xml}{glLinkProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glReleaseShaderCompiler()
+
+ Convenience function that calls glReleaseShaderCompiler().
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glReleaseShaderCompiler.xml}{glReleaseShaderCompiler()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+
+ Convenience function that calls glRenderbufferStorage(\a target, \a internalformat, \a width, \a height).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glRenderbufferStorage.xml}{glRenderbufferStorage()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert)
+
+ Convenience function that calls glSampleCoverage(\a value, \a invert).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glSampleCoverage.xml}{glSampleCoverage()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
+
+ Convenience function that calls glShaderBinary(\a n, \a shaders, \a binaryformat, \a binary, \a length).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glShaderBinary.xml}{glShaderBinary()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+
+ Convenience function that calls glShaderSource(\a shader, \a count, \a string, \a length).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glShaderSource.xml}{glShaderSource()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+
+ Convenience function that calls glStencilFuncSeparate(\a face, \a func, \a ref, \a mask).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilFuncSeparate.xml}{glStencilFuncSeparate()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glStencilMaskSeparate(GLenum face, GLuint mask)
+
+ Convenience function that calls glStencilMaskSeparate(\a face, \a mask).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilMaskSeparate.xml}{glStencilMaskSeparate()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+
+ Convenience function that calls glStencilOpSeparate(\a face, \a fail, \a zfail, \a zpass).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilOpSeparate.xml}{glStencilOpSeparate()}.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform1f(GLint location, GLfloat x)
+
+ Convenience function that calls glUniform1f(\a location, \a x).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1f.xml}{glUniform1f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform1fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1fv.xml}{glUniform1fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform1i(GLint location, GLint x)
+
+ Convenience function that calls glUniform1i(\a location, \a x).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1i.xml}{glUniform1i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform1iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform1iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1iv.xml}{glUniform1iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform2f(GLint location, GLfloat x, GLfloat y)
+
+ Convenience function that calls glUniform2f(\a location, \a x, \a y).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2f.xml}{glUniform2f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform2fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2fv.xml}{glUniform2fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform2i(GLint location, GLint x, GLint y)
+
+ Convenience function that calls glUniform2i(\a location, \a x, \a y).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2i.xml}{glUniform2i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform2iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform2iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2iv.xml}{glUniform2iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+
+ Convenience function that calls glUniform3f(\a location, \a x, \a y, \a z).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3f.xml}{glUniform3f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform3fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3fv.xml}{glUniform3fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform3i(GLint location, GLint x, GLint y, GLint z)
+
+ Convenience function that calls glUniform3i(\a location, \a x, \a y, \a z).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3i.xml}{glUniform3i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform3iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform3iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3iv.xml}{glUniform3iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+
+ Convenience function that calls glUniform4f(\a location, \a x, \a y, \a z, \a w).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4f.xml}{glUniform4f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform4fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4fv.xml}{glUniform4fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+
+ Convenience function that calls glUniform4i(\a location, \a x, \a y, \a z, \a w).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4i.xml}{glUniform4i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniform4iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform4iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4iv.xml}{glUniform4iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+
+ Convenience function that calls glUniformMatrix2fv(\a location, \a count, \a transpose, \a value).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix2fv.xml}{glUniformMatrix2fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+
+ Convenience function that calls glUniformMatrix3fv(\a location, \a count, \a transpose, \a value).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix3fv.xml}{glUniformMatrix3fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+
+ Convenience function that calls glUniformMatrix4fv(\a location, \a count, \a transpose, \a value).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix4fv.xml}{glUniformMatrix4fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glUseProgram(GLuint program)
+
+ Convenience function that calls glUseProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUseProgram.xml}{glUseProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glValidateProgram(GLuint program)
+
+ Convenience function that calls glValidateProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glValidateProgram.xml}{glValidateProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib1f(GLuint indx, GLfloat x)
+
+ Convenience function that calls glVertexAttrib1f(\a indx, \a x).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1f.xml}{glVertexAttrib1f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib1fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1fv.xml}{glVertexAttrib1fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+
+ Convenience function that calls glVertexAttrib2f(\a indx, \a x, \a y).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2f.xml}{glVertexAttrib2f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib2fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2fv.xml}{glVertexAttrib2fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+
+ Convenience function that calls glVertexAttrib3f(\a indx, \a x, \a y, \a z).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3f.xml}{glVertexAttrib3f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib3fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3fv.xml}{glVertexAttrib3fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+
+ Convenience function that calls glVertexAttrib4f(\a indx, \a x, \a y, \a z, \a w).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4f.xml}{glVertexAttrib4f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib4fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4fv.xml}{glVertexAttrib4fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+
+ Convenience function that calls glVertexAttribPointer(\a indx, \a size, \a type, \a normalized, \a stride, \a ptr).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttribPointer.xml}{glVertexAttribPointer()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+#ifndef QT_OPENGL_ES_2
+
+static void qglfResolveActiveTexture(GLenum texture)
+{
+ typedef void (QGLF_APIENTRYP type_glActiveTexture)(GLenum texture);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->activeTexture = (type_glActiveTexture)
+ context->getProcAddress(QLatin1String("glActiveTexture"));
+ if (!funcs->activeTexture) {
+ funcs->activeTexture = (type_glActiveTexture)
+ context->getProcAddress(QLatin1String("glActiveTextureARB"));
+ }
+
+ if (funcs->activeTexture)
+ funcs->activeTexture(texture);
+ else
+ funcs->activeTexture = qglfResolveActiveTexture;
+}
+
+static void qglfResolveAttachShader(GLuint program, GLuint shader)
+{
+ typedef void (QGLF_APIENTRYP type_glAttachShader)(GLuint program, GLuint shader);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->attachShader = (type_glAttachShader)
+ context->getProcAddress(QLatin1String("glAttachShader"));
+ if (!funcs->attachShader) {
+ funcs->attachShader = (type_glAttachShader)
+ context->getProcAddress(QLatin1String("glAttachObjectARB"));
+ }
+
+ if (funcs->attachShader)
+ funcs->attachShader(program, shader);
+ else
+ funcs->attachShader = qglfResolveAttachShader;
+}
+
+static void qglfResolveBindAttribLocation(GLuint program, GLuint index, const char* name)
+{
+ typedef void (QGLF_APIENTRYP type_glBindAttribLocation)(GLuint program, GLuint index, const char* name);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->bindAttribLocation = (type_glBindAttribLocation)
+ context->getProcAddress(QLatin1String("glBindAttribLocation"));
+ if (!funcs->bindAttribLocation) {
+ funcs->bindAttribLocation = (type_glBindAttribLocation)
+ context->getProcAddress(QLatin1String("glBindAttribLocationARB"));
+ }
+
+ if (funcs->bindAttribLocation)
+ funcs->bindAttribLocation(program, index, name);
+ else
+ funcs->bindAttribLocation = qglfResolveBindAttribLocation;
+}
+
+static void qglfResolveBindBuffer(GLenum target, GLuint buffer)
+{
+ typedef void (QGLF_APIENTRYP type_glBindBuffer)(GLenum target, GLuint buffer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->bindBuffer = (type_glBindBuffer)
+ context->getProcAddress(QLatin1String("glBindBuffer"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->bindBuffer) {
+ funcs->bindBuffer = (type_glBindBuffer)
+ context->getProcAddress(QLatin1String("glBindBufferOES"));
+ }
+#endif
+ if (!funcs->bindBuffer) {
+ funcs->bindBuffer = (type_glBindBuffer)
+ context->getProcAddress(QLatin1String("glBindBufferEXT"));
+ }
+ if (!funcs->bindBuffer) {
+ funcs->bindBuffer = (type_glBindBuffer)
+ context->getProcAddress(QLatin1String("glBindBufferARB"));
+ }
+
+ if (funcs->bindBuffer)
+ funcs->bindBuffer(target, buffer);
+ else
+ funcs->bindBuffer = qglfResolveBindBuffer;
+}
+
+static void qglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ typedef void (QGLF_APIENTRYP type_glBindFramebuffer)(GLenum target, GLuint framebuffer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->bindFramebuffer = (type_glBindFramebuffer)
+ context->getProcAddress(QLatin1String("glBindFramebuffer"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->bindFramebuffer) {
+ funcs->bindFramebuffer = (type_glBindFramebuffer)
+ context->getProcAddress(QLatin1String("glBindFramebufferOES"));
+ }
+#endif
+ if (!funcs->bindFramebuffer) {
+ funcs->bindFramebuffer = (type_glBindFramebuffer)
+ context->getProcAddress(QLatin1String("glBindFramebufferEXT"));
+ }
+ if (!funcs->bindFramebuffer) {
+ funcs->bindFramebuffer = (type_glBindFramebuffer)
+ context->getProcAddress(QLatin1String("glBindFramebufferARB"));
+ }
+
+ if (funcs->bindFramebuffer)
+ funcs->bindFramebuffer(target, framebuffer);
+ else
+ funcs->bindFramebuffer = qglfResolveBindFramebuffer;
+}
+
+static void qglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ typedef void (QGLF_APIENTRYP type_glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->bindRenderbuffer = (type_glBindRenderbuffer)
+ context->getProcAddress(QLatin1String("glBindRenderbuffer"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->bindRenderbuffer) {
+ funcs->bindRenderbuffer = (type_glBindRenderbuffer)
+ context->getProcAddress(QLatin1String("glBindRenderbufferOES"));
+ }
+#endif
+ if (!funcs->bindRenderbuffer) {
+ funcs->bindRenderbuffer = (type_glBindRenderbuffer)
+ context->getProcAddress(QLatin1String("glBindRenderbufferEXT"));
+ }
+ if (!funcs->bindRenderbuffer) {
+ funcs->bindRenderbuffer = (type_glBindRenderbuffer)
+ context->getProcAddress(QLatin1String("glBindRenderbufferARB"));
+ }
+
+ if (funcs->bindRenderbuffer)
+ funcs->bindRenderbuffer(target, renderbuffer);
+ else
+ funcs->bindRenderbuffer = qglfResolveBindRenderbuffer;
+}
+
+static void qglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ typedef void (QGLF_APIENTRYP type_glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->blendColor = (type_glBlendColor)
+ context->getProcAddress(QLatin1String("glBlendColor"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->blendColor) {
+ funcs->blendColor = (type_glBlendColor)
+ context->getProcAddress(QLatin1String("glBlendColorOES"));
+ }
+#endif
+ if (!funcs->blendColor) {
+ funcs->blendColor = (type_glBlendColor)
+ context->getProcAddress(QLatin1String("glBlendColorEXT"));
+ }
+ if (!funcs->blendColor) {
+ funcs->blendColor = (type_glBlendColor)
+ context->getProcAddress(QLatin1String("glBlendColorARB"));
+ }
+
+ if (funcs->blendColor)
+ funcs->blendColor(red, green, blue, alpha);
+ else
+ funcs->blendColor = qglfResolveBlendColor;
+}
+
+static void qglfResolveBlendEquation(GLenum mode)
+{
+ typedef void (QGLF_APIENTRYP type_glBlendEquation)(GLenum mode);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->blendEquation = (type_glBlendEquation)
+ context->getProcAddress(QLatin1String("glBlendEquation"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->blendEquation) {
+ funcs->blendEquation = (type_glBlendEquation)
+ context->getProcAddress(QLatin1String("glBlendEquationOES"));
+ }
+#endif
+ if (!funcs->blendEquation) {
+ funcs->blendEquation = (type_glBlendEquation)
+ context->getProcAddress(QLatin1String("glBlendEquationEXT"));
+ }
+ if (!funcs->blendEquation) {
+ funcs->blendEquation = (type_glBlendEquation)
+ context->getProcAddress(QLatin1String("glBlendEquationARB"));
+ }
+
+ if (funcs->blendEquation)
+ funcs->blendEquation(mode);
+ else
+ funcs->blendEquation = qglfResolveBlendEquation;
+}
+
+static void qglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ typedef void (QGLF_APIENTRYP type_glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->blendEquationSeparate = (type_glBlendEquationSeparate)
+ context->getProcAddress(QLatin1String("glBlendEquationSeparate"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->blendEquationSeparate) {
+ funcs->blendEquationSeparate = (type_glBlendEquationSeparate)
+ context->getProcAddress(QLatin1String("glBlendEquationSeparateOES"));
+ }
+#endif
+ if (!funcs->blendEquationSeparate) {
+ funcs->blendEquationSeparate = (type_glBlendEquationSeparate)
+ context->getProcAddress(QLatin1String("glBlendEquationSeparateEXT"));
+ }
+ if (!funcs->blendEquationSeparate) {
+ funcs->blendEquationSeparate = (type_glBlendEquationSeparate)
+ context->getProcAddress(QLatin1String("glBlendEquationSeparateARB"));
+ }
+
+ if (funcs->blendEquationSeparate)
+ funcs->blendEquationSeparate(modeRGB, modeAlpha);
+ else
+ funcs->blendEquationSeparate = qglfResolveBlendEquationSeparate;
+}
+
+static void qglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ typedef void (QGLF_APIENTRYP type_glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->blendFuncSeparate = (type_glBlendFuncSeparate)
+ context->getProcAddress(QLatin1String("glBlendFuncSeparate"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->blendFuncSeparate) {
+ funcs->blendFuncSeparate = (type_glBlendFuncSeparate)
+ context->getProcAddress(QLatin1String("glBlendFuncSeparateOES"));
+ }
+#endif
+ if (!funcs->blendFuncSeparate) {
+ funcs->blendFuncSeparate = (type_glBlendFuncSeparate)
+ context->getProcAddress(QLatin1String("glBlendFuncSeparateEXT"));
+ }
+ if (!funcs->blendFuncSeparate) {
+ funcs->blendFuncSeparate = (type_glBlendFuncSeparate)
+ context->getProcAddress(QLatin1String("glBlendFuncSeparateARB"));
+ }
+
+ if (funcs->blendFuncSeparate)
+ funcs->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+ else
+ funcs->blendFuncSeparate = qglfResolveBlendFuncSeparate;
+}
+
+static void qglfResolveBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
+{
+ typedef void (QGLF_APIENTRYP type_glBufferData)(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->bufferData = (type_glBufferData)
+ context->getProcAddress(QLatin1String("glBufferData"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->bufferData) {
+ funcs->bufferData = (type_glBufferData)
+ context->getProcAddress(QLatin1String("glBufferDataOES"));
+ }
+#endif
+ if (!funcs->bufferData) {
+ funcs->bufferData = (type_glBufferData)
+ context->getProcAddress(QLatin1String("glBufferDataEXT"));
+ }
+ if (!funcs->bufferData) {
+ funcs->bufferData = (type_glBufferData)
+ context->getProcAddress(QLatin1String("glBufferDataARB"));
+ }
+
+ if (funcs->bufferData)
+ funcs->bufferData(target, size, data, usage);
+ else
+ funcs->bufferData = qglfResolveBufferData;
+}
+
+static void qglfResolveBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
+{
+ typedef void (QGLF_APIENTRYP type_glBufferSubData)(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->bufferSubData = (type_glBufferSubData)
+ context->getProcAddress(QLatin1String("glBufferSubData"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->bufferSubData) {
+ funcs->bufferSubData = (type_glBufferSubData)
+ context->getProcAddress(QLatin1String("glBufferSubDataOES"));
+ }
+#endif
+ if (!funcs->bufferSubData) {
+ funcs->bufferSubData = (type_glBufferSubData)
+ context->getProcAddress(QLatin1String("glBufferSubDataEXT"));
+ }
+ if (!funcs->bufferSubData) {
+ funcs->bufferSubData = (type_glBufferSubData)
+ context->getProcAddress(QLatin1String("glBufferSubDataARB"));
+ }
+
+ if (funcs->bufferSubData)
+ funcs->bufferSubData(target, offset, size, data);
+ else
+ funcs->bufferSubData = qglfResolveBufferSubData;
+}
+
+static GLenum qglfResolveCheckFramebufferStatus(GLenum target)
+{
+ typedef GLenum (QGLF_APIENTRYP type_glCheckFramebufferStatus)(GLenum target);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->checkFramebufferStatus = (type_glCheckFramebufferStatus)
+ context->getProcAddress(QLatin1String("glCheckFramebufferStatus"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->checkFramebufferStatus) {
+ funcs->checkFramebufferStatus = (type_glCheckFramebufferStatus)
+ context->getProcAddress(QLatin1String("glCheckFramebufferStatusOES"));
+ }
+#endif
+ if (!funcs->checkFramebufferStatus) {
+ funcs->checkFramebufferStatus = (type_glCheckFramebufferStatus)
+ context->getProcAddress(QLatin1String("glCheckFramebufferStatusEXT"));
+ }
+ if (!funcs->checkFramebufferStatus) {
+ funcs->checkFramebufferStatus = (type_glCheckFramebufferStatus)
+ context->getProcAddress(QLatin1String("glCheckFramebufferStatusARB"));
+ }
+
+ if (funcs->checkFramebufferStatus)
+ return funcs->checkFramebufferStatus(target);
+ funcs->checkFramebufferStatus = qglfResolveCheckFramebufferStatus;
+ return GLenum(0);
+}
+
+static void qglfResolveCompileShader(GLuint shader)
+{
+ typedef void (QGLF_APIENTRYP type_glCompileShader)(GLuint shader);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->compileShader = (type_glCompileShader)
+ context->getProcAddress(QLatin1String("glCompileShader"));
+ if (!funcs->compileShader) {
+ funcs->compileShader = (type_glCompileShader)
+ context->getProcAddress(QLatin1String("glCompileShader"));
+ }
+
+ if (funcs->compileShader)
+ funcs->compileShader(shader);
+ else
+ funcs->compileShader = qglfResolveCompileShader;
+}
+
+static void qglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+{
+ typedef void (QGLF_APIENTRYP type_glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->compressedTexImage2D = (type_glCompressedTexImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexImage2D"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->compressedTexImage2D) {
+ funcs->compressedTexImage2D = (type_glCompressedTexImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexImage2DOES"));
+ }
+#endif
+ if (!funcs->compressedTexImage2D) {
+ funcs->compressedTexImage2D = (type_glCompressedTexImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexImage2DEXT"));
+ }
+ if (!funcs->compressedTexImage2D) {
+ funcs->compressedTexImage2D = (type_glCompressedTexImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
+ }
+
+ if (funcs->compressedTexImage2D)
+ funcs->compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+ else
+ funcs->compressedTexImage2D = qglfResolveCompressedTexImage2D;
+}
+
+static void qglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+{
+ typedef void (QGLF_APIENTRYP type_glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->compressedTexSubImage2D = (type_glCompressedTexSubImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexSubImage2D"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->compressedTexSubImage2D) {
+ funcs->compressedTexSubImage2D = (type_glCompressedTexSubImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexSubImage2DOES"));
+ }
+#endif
+ if (!funcs->compressedTexSubImage2D) {
+ funcs->compressedTexSubImage2D = (type_glCompressedTexSubImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexSubImage2DEXT"));
+ }
+ if (!funcs->compressedTexSubImage2D) {
+ funcs->compressedTexSubImage2D = (type_glCompressedTexSubImage2D)
+ context->getProcAddress(QLatin1String("glCompressedTexSubImage2DARB"));
+ }
+
+ if (funcs->compressedTexSubImage2D)
+ funcs->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ else
+ funcs->compressedTexSubImage2D = qglfResolveCompressedTexSubImage2D;
+}
+
+static GLuint qglfResolveCreateProgram()
+{
+ typedef GLuint (QGLF_APIENTRYP type_glCreateProgram)();
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->createProgram = (type_glCreateProgram)
+ context->getProcAddress(QLatin1String("glCreateProgram"));
+ if (!funcs->createProgram) {
+ funcs->createProgram = (type_glCreateProgram)
+ context->getProcAddress(QLatin1String("glCreateProgramObjectARB"));
+ }
+
+ if (funcs->createProgram)
+ return funcs->createProgram();
+ funcs->createProgram = qglfResolveCreateProgram;
+ return GLuint(0);
+}
+
+static GLuint qglfResolveCreateShader(GLenum type)
+{
+ typedef GLuint (QGLF_APIENTRYP type_glCreateShader)(GLenum type);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->createShader = (type_glCreateShader)
+ context->getProcAddress(QLatin1String("glCreateShader"));
+ if (!funcs->createShader) {
+ funcs->createShader = (type_glCreateShader)
+ context->getProcAddress(QLatin1String("glCreateShaderObjectARB"));
+ }
+
+ if (funcs->createShader)
+ return funcs->createShader(type);
+ funcs->createShader = qglfResolveCreateShader;
+ return GLuint(0);
+}
+
+static void qglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ typedef void (QGLF_APIENTRYP type_glDeleteBuffers)(GLsizei n, const GLuint* buffers);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->deleteBuffers = (type_glDeleteBuffers)
+ context->getProcAddress(QLatin1String("glDeleteBuffers"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->deleteBuffers) {
+ funcs->deleteBuffers = (type_glDeleteBuffers)
+ context->getProcAddress(QLatin1String("glDeleteBuffersOES"));
+ }
+#endif
+ if (!funcs->deleteBuffers) {
+ funcs->deleteBuffers = (type_glDeleteBuffers)
+ context->getProcAddress(QLatin1String("glDeleteBuffersEXT"));
+ }
+ if (!funcs->deleteBuffers) {
+ funcs->deleteBuffers = (type_glDeleteBuffers)
+ context->getProcAddress(QLatin1String("glDeleteBuffersARB"));
+ }
+
+ if (funcs->deleteBuffers)
+ funcs->deleteBuffers(n, buffers);
+ else
+ funcs->deleteBuffers = qglfResolveDeleteBuffers;
+}
+
+static void qglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+ typedef void (QGLF_APIENTRYP type_glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->deleteFramebuffers = (type_glDeleteFramebuffers)
+ context->getProcAddress(QLatin1String("glDeleteFramebuffers"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->deleteFramebuffers) {
+ funcs->deleteFramebuffers = (type_glDeleteFramebuffers)
+ context->getProcAddress(QLatin1String("glDeleteFramebuffersOES"));
+ }
+#endif
+ if (!funcs->deleteFramebuffers) {
+ funcs->deleteFramebuffers = (type_glDeleteFramebuffers)
+ context->getProcAddress(QLatin1String("glDeleteFramebuffersEXT"));
+ }
+ if (!funcs->deleteFramebuffers) {
+ funcs->deleteFramebuffers = (type_glDeleteFramebuffers)
+ context->getProcAddress(QLatin1String("glDeleteFramebuffersARB"));
+ }
+
+ if (funcs->deleteFramebuffers)
+ funcs->deleteFramebuffers(n, framebuffers);
+ else
+ funcs->deleteFramebuffers = qglfResolveDeleteFramebuffers;
+}
+
+static void qglfResolveDeleteProgram(GLuint program)
+{
+ typedef void (QGLF_APIENTRYP type_glDeleteProgram)(GLuint program);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->deleteProgram = (type_glDeleteProgram)
+ context->getProcAddress(QLatin1String("glDeleteProgram"));
+ if (!funcs->deleteProgram) {
+ funcs->deleteProgram = (type_glDeleteProgram)
+ context->getProcAddress(QLatin1String("glDeleteObjectARB"));
+ }
+
+ if (funcs->deleteProgram)
+ funcs->deleteProgram(program);
+ else
+ funcs->deleteProgram = qglfResolveDeleteProgram;
+}
+
+static void qglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+ typedef void (QGLF_APIENTRYP type_glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->deleteRenderbuffers = (type_glDeleteRenderbuffers)
+ context->getProcAddress(QLatin1String("glDeleteRenderbuffers"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->deleteRenderbuffers) {
+ funcs->deleteRenderbuffers = (type_glDeleteRenderbuffers)
+ context->getProcAddress(QLatin1String("glDeleteRenderbuffersOES"));
+ }
+#endif
+ if (!funcs->deleteRenderbuffers) {
+ funcs->deleteRenderbuffers = (type_glDeleteRenderbuffers)
+ context->getProcAddress(QLatin1String("glDeleteRenderbuffersEXT"));
+ }
+ if (!funcs->deleteRenderbuffers) {
+ funcs->deleteRenderbuffers = (type_glDeleteRenderbuffers)
+ context->getProcAddress(QLatin1String("glDeleteRenderbuffersARB"));
+ }
+
+ if (funcs->deleteRenderbuffers)
+ funcs->deleteRenderbuffers(n, renderbuffers);
+ else
+ funcs->deleteRenderbuffers = qglfResolveDeleteRenderbuffers;
+}
+
+static void qglfResolveDeleteShader(GLuint shader)
+{
+ typedef void (QGLF_APIENTRYP type_glDeleteShader)(GLuint shader);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->deleteShader = (type_glDeleteShader)
+ context->getProcAddress(QLatin1String("glDeleteShader"));
+ if (!funcs->deleteShader) {
+ funcs->deleteShader = (type_glDeleteShader)
+ context->getProcAddress(QLatin1String("glDeleteObjectARB"));
+ }
+
+ if (funcs->deleteShader)
+ funcs->deleteShader(shader);
+ else
+ funcs->deleteShader = qglfResolveDeleteShader;
+}
+
+static void qglfResolveDetachShader(GLuint program, GLuint shader)
+{
+ typedef void (QGLF_APIENTRYP type_glDetachShader)(GLuint program, GLuint shader);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->detachShader = (type_glDetachShader)
+ context->getProcAddress(QLatin1String("glDetachShader"));
+ if (!funcs->detachShader) {
+ funcs->detachShader = (type_glDetachShader)
+ context->getProcAddress(QLatin1String("glDetachObjectARB"));
+ }
+
+ if (funcs->detachShader)
+ funcs->detachShader(program, shader);
+ else
+ funcs->detachShader = qglfResolveDetachShader;
+}
+
+static void qglfResolveDisableVertexAttribArray(GLuint index)
+{
+ typedef void (QGLF_APIENTRYP type_glDisableVertexAttribArray)(GLuint index);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->disableVertexAttribArray = (type_glDisableVertexAttribArray)
+ context->getProcAddress(QLatin1String("glDisableVertexAttribArray"));
+ if (!funcs->disableVertexAttribArray) {
+ funcs->disableVertexAttribArray = (type_glDisableVertexAttribArray)
+ context->getProcAddress(QLatin1String("glDisableVertexAttribArrayARB"));
+ }
+
+ if (funcs->disableVertexAttribArray)
+ funcs->disableVertexAttribArray(index);
+ else
+ funcs->disableVertexAttribArray = qglfResolveDisableVertexAttribArray;
+}
+
+static void qglfResolveEnableVertexAttribArray(GLuint index)
+{
+ typedef void (QGLF_APIENTRYP type_glEnableVertexAttribArray)(GLuint index);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->enableVertexAttribArray = (type_glEnableVertexAttribArray)
+ context->getProcAddress(QLatin1String("glEnableVertexAttribArray"));
+ if (!funcs->enableVertexAttribArray) {
+ funcs->enableVertexAttribArray = (type_glEnableVertexAttribArray)
+ context->getProcAddress(QLatin1String("glEnableVertexAttribArrayARB"));
+ }
+
+ if (funcs->enableVertexAttribArray)
+ funcs->enableVertexAttribArray(index);
+ else
+ funcs->enableVertexAttribArray = qglfResolveEnableVertexAttribArray;
+}
+
+static void qglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ typedef void (QGLF_APIENTRYP type_glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->framebufferRenderbuffer = (type_glFramebufferRenderbuffer)
+ context->getProcAddress(QLatin1String("glFramebufferRenderbuffer"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->framebufferRenderbuffer) {
+ funcs->framebufferRenderbuffer = (type_glFramebufferRenderbuffer)
+ context->getProcAddress(QLatin1String("glFramebufferRenderbufferOES"));
+ }
+#endif
+ if (!funcs->framebufferRenderbuffer) {
+ funcs->framebufferRenderbuffer = (type_glFramebufferRenderbuffer)
+ context->getProcAddress(QLatin1String("glFramebufferRenderbufferEXT"));
+ }
+ if (!funcs->framebufferRenderbuffer) {
+ funcs->framebufferRenderbuffer = (type_glFramebufferRenderbuffer)
+ context->getProcAddress(QLatin1String("glFramebufferRenderbufferARB"));
+ }
+
+ if (funcs->framebufferRenderbuffer)
+ funcs->framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+ else
+ funcs->framebufferRenderbuffer = qglfResolveFramebufferRenderbuffer;
+}
+
+static void qglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ typedef void (QGLF_APIENTRYP type_glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->framebufferTexture2D = (type_glFramebufferTexture2D)
+ context->getProcAddress(QLatin1String("glFramebufferTexture2D"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->framebufferTexture2D) {
+ funcs->framebufferTexture2D = (type_glFramebufferTexture2D)
+ context->getProcAddress(QLatin1String("glFramebufferTexture2DOES"));
+ }
+#endif
+ if (!funcs->framebufferTexture2D) {
+ funcs->framebufferTexture2D = (type_glFramebufferTexture2D)
+ context->getProcAddress(QLatin1String("glFramebufferTexture2DEXT"));
+ }
+ if (!funcs->framebufferTexture2D) {
+ funcs->framebufferTexture2D = (type_glFramebufferTexture2D)
+ context->getProcAddress(QLatin1String("glFramebufferTexture2DARB"));
+ }
+
+ if (funcs->framebufferTexture2D)
+ funcs->framebufferTexture2D(target, attachment, textarget, texture, level);
+ else
+ funcs->framebufferTexture2D = qglfResolveFramebufferTexture2D;
+}
+
+static void qglfResolveGenBuffers(GLsizei n, GLuint* buffers)
+{
+ typedef void (QGLF_APIENTRYP type_glGenBuffers)(GLsizei n, GLuint* buffers);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->genBuffers = (type_glGenBuffers)
+ context->getProcAddress(QLatin1String("glGenBuffers"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->genBuffers) {
+ funcs->genBuffers = (type_glGenBuffers)
+ context->getProcAddress(QLatin1String("glGenBuffersOES"));
+ }
+#endif
+ if (!funcs->genBuffers) {
+ funcs->genBuffers = (type_glGenBuffers)
+ context->getProcAddress(QLatin1String("glGenBuffersEXT"));
+ }
+ if (!funcs->genBuffers) {
+ funcs->genBuffers = (type_glGenBuffers)
+ context->getProcAddress(QLatin1String("glGenBuffersARB"));
+ }
+
+ if (funcs->genBuffers)
+ funcs->genBuffers(n, buffers);
+ else
+ funcs->genBuffers = qglfResolveGenBuffers;
+}
+
+static void qglfResolveGenerateMipmap(GLenum target)
+{
+ typedef void (QGLF_APIENTRYP type_glGenerateMipmap)(GLenum target);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->generateMipmap = (type_glGenerateMipmap)
+ context->getProcAddress(QLatin1String("glGenerateMipmap"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->generateMipmap) {
+ funcs->generateMipmap = (type_glGenerateMipmap)
+ context->getProcAddress(QLatin1String("glGenerateMipmapOES"));
+ }
+#endif
+ if (!funcs->generateMipmap) {
+ funcs->generateMipmap = (type_glGenerateMipmap)
+ context->getProcAddress(QLatin1String("glGenerateMipmapEXT"));
+ }
+ if (!funcs->generateMipmap) {
+ funcs->generateMipmap = (type_glGenerateMipmap)
+ context->getProcAddress(QLatin1String("glGenerateMipmapARB"));
+ }
+
+ if (funcs->generateMipmap)
+ funcs->generateMipmap(target);
+ else
+ funcs->generateMipmap = qglfResolveGenerateMipmap;
+}
+
+static void qglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+ typedef void (QGLF_APIENTRYP type_glGenFramebuffers)(GLsizei n, GLuint* framebuffers);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->genFramebuffers = (type_glGenFramebuffers)
+ context->getProcAddress(QLatin1String("glGenFramebuffers"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->genFramebuffers) {
+ funcs->genFramebuffers = (type_glGenFramebuffers)
+ context->getProcAddress(QLatin1String("glGenFramebuffersOES"));
+ }
+#endif
+ if (!funcs->genFramebuffers) {
+ funcs->genFramebuffers = (type_glGenFramebuffers)
+ context->getProcAddress(QLatin1String("glGenFramebuffersEXT"));
+ }
+ if (!funcs->genFramebuffers) {
+ funcs->genFramebuffers = (type_glGenFramebuffers)
+ context->getProcAddress(QLatin1String("glGenFramebuffersARB"));
+ }
+
+ if (funcs->genFramebuffers)
+ funcs->genFramebuffers(n, framebuffers);
+ else
+ funcs->genFramebuffers = qglfResolveGenFramebuffers;
+}
+
+static void qglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+ typedef void (QGLF_APIENTRYP type_glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->genRenderbuffers = (type_glGenRenderbuffers)
+ context->getProcAddress(QLatin1String("glGenRenderbuffers"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->genRenderbuffers) {
+ funcs->genRenderbuffers = (type_glGenRenderbuffers)
+ context->getProcAddress(QLatin1String("glGenRenderbuffersOES"));
+ }
+#endif
+ if (!funcs->genRenderbuffers) {
+ funcs->genRenderbuffers = (type_glGenRenderbuffers)
+ context->getProcAddress(QLatin1String("glGenRenderbuffersEXT"));
+ }
+ if (!funcs->genRenderbuffers) {
+ funcs->genRenderbuffers = (type_glGenRenderbuffers)
+ context->getProcAddress(QLatin1String("glGenRenderbuffersARB"));
+ }
+
+ if (funcs->genRenderbuffers)
+ funcs->genRenderbuffers(n, renderbuffers);
+ else
+ funcs->genRenderbuffers = qglfResolveGenRenderbuffers;
+}
+
+static void qglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+ typedef void (QGLF_APIENTRYP type_glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getActiveAttrib = (type_glGetActiveAttrib)
+ context->getProcAddress(QLatin1String("glGetActiveAttrib"));
+ if (!funcs->getActiveAttrib) {
+ funcs->getActiveAttrib = (type_glGetActiveAttrib)
+ context->getProcAddress(QLatin1String("glGetActiveAttribARB"));
+ }
+
+ if (funcs->getActiveAttrib)
+ funcs->getActiveAttrib(program, index, bufsize, length, size, type, name);
+ else
+ funcs->getActiveAttrib = qglfResolveGetActiveAttrib;
+}
+
+static void qglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+ typedef void (QGLF_APIENTRYP type_glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getActiveUniform = (type_glGetActiveUniform)
+ context->getProcAddress(QLatin1String("glGetActiveUniform"));
+ if (!funcs->getActiveUniform) {
+ funcs->getActiveUniform = (type_glGetActiveUniform)
+ context->getProcAddress(QLatin1String("glGetActiveUniformARB"));
+ }
+
+ if (funcs->getActiveUniform)
+ funcs->getActiveUniform(program, index, bufsize, length, size, type, name);
+ else
+ funcs->getActiveUniform = qglfResolveGetActiveUniform;
+}
+
+static void qglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ typedef void (QGLF_APIENTRYP type_glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getAttachedShaders = (type_glGetAttachedShaders)
+ context->getProcAddress(QLatin1String("glGetAttachedShaders"));
+ if (!funcs->getAttachedShaders) {
+ funcs->getAttachedShaders = (type_glGetAttachedShaders)
+ context->getProcAddress(QLatin1String("glGetAttachedObjectsARB"));
+ }
+
+ if (funcs->getAttachedShaders)
+ funcs->getAttachedShaders(program, maxcount, count, shaders);
+ else
+ funcs->getAttachedShaders = qglfResolveGetAttachedShaders;
+}
+
+static int qglfResolveGetAttribLocation(GLuint program, const char* name)
+{
+ typedef int (QGLF_APIENTRYP type_glGetAttribLocation)(GLuint program, const char* name);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getAttribLocation = (type_glGetAttribLocation)
+ context->getProcAddress(QLatin1String("glGetAttribLocation"));
+ if (!funcs->getAttribLocation) {
+ funcs->getAttribLocation = (type_glGetAttribLocation)
+ context->getProcAddress(QLatin1String("glGetAttribLocationARB"));
+ }
+
+ if (funcs->getAttribLocation)
+ return funcs->getAttribLocation(program, name);
+ funcs->getAttribLocation = qglfResolveGetAttribLocation;
+ return int(0);
+}
+
+static void qglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getBufferParameteriv = (type_glGetBufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetBufferParameteriv"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->getBufferParameteriv) {
+ funcs->getBufferParameteriv = (type_glGetBufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetBufferParameterivOES"));
+ }
+#endif
+ if (!funcs->getBufferParameteriv) {
+ funcs->getBufferParameteriv = (type_glGetBufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetBufferParameterivEXT"));
+ }
+ if (!funcs->getBufferParameteriv) {
+ funcs->getBufferParameteriv = (type_glGetBufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetBufferParameterivARB"));
+ }
+
+ if (funcs->getBufferParameteriv)
+ funcs->getBufferParameteriv(target, pname, params);
+ else
+ funcs->getBufferParameteriv = qglfResolveGetBufferParameteriv;
+}
+
+static void qglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getFramebufferAttachmentParameteriv = (type_glGetFramebufferAttachmentParameteriv)
+ context->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameteriv"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->getFramebufferAttachmentParameteriv) {
+ funcs->getFramebufferAttachmentParameteriv = (type_glGetFramebufferAttachmentParameteriv)
+ context->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameterivOES"));
+ }
+#endif
+ if (!funcs->getFramebufferAttachmentParameteriv) {
+ funcs->getFramebufferAttachmentParameteriv = (type_glGetFramebufferAttachmentParameteriv)
+ context->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameterivEXT"));
+ }
+ if (!funcs->getFramebufferAttachmentParameteriv) {
+ funcs->getFramebufferAttachmentParameteriv = (type_glGetFramebufferAttachmentParameteriv)
+ context->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameterivARB"));
+ }
+
+ if (funcs->getFramebufferAttachmentParameteriv)
+ funcs->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
+ else
+ funcs->getFramebufferAttachmentParameteriv = qglfResolveGetFramebufferAttachmentParameteriv;
+}
+
+static void qglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetProgramiv)(GLuint program, GLenum pname, GLint* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getProgramiv = (type_glGetProgramiv)
+ context->getProcAddress(QLatin1String("glGetProgramiv"));
+ if (!funcs->getProgramiv) {
+ funcs->getProgramiv = (type_glGetProgramiv)
+ context->getProcAddress(QLatin1String("glGetObjectParameterivARB"));
+ }
+
+ if (funcs->getProgramiv)
+ funcs->getProgramiv(program, pname, params);
+ else
+ funcs->getProgramiv = qglfResolveGetProgramiv;
+}
+
+static void qglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+ typedef void (QGLF_APIENTRYP type_glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getProgramInfoLog = (type_glGetProgramInfoLog)
+ context->getProcAddress(QLatin1String("glGetProgramInfoLog"));
+ if (!funcs->getProgramInfoLog) {
+ funcs->getProgramInfoLog = (type_glGetProgramInfoLog)
+ context->getProcAddress(QLatin1String("glGetInfoLogARB"));
+ }
+
+ if (funcs->getProgramInfoLog)
+ funcs->getProgramInfoLog(program, bufsize, length, infolog);
+ else
+ funcs->getProgramInfoLog = qglfResolveGetProgramInfoLog;
+}
+
+static void qglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getRenderbufferParameteriv = (type_glGetRenderbufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetRenderbufferParameteriv"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->getRenderbufferParameteriv) {
+ funcs->getRenderbufferParameteriv = (type_glGetRenderbufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetRenderbufferParameterivOES"));
+ }
+#endif
+ if (!funcs->getRenderbufferParameteriv) {
+ funcs->getRenderbufferParameteriv = (type_glGetRenderbufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetRenderbufferParameterivEXT"));
+ }
+ if (!funcs->getRenderbufferParameteriv) {
+ funcs->getRenderbufferParameteriv = (type_glGetRenderbufferParameteriv)
+ context->getProcAddress(QLatin1String("glGetRenderbufferParameterivARB"));
+ }
+
+ if (funcs->getRenderbufferParameteriv)
+ funcs->getRenderbufferParameteriv(target, pname, params);
+ else
+ funcs->getRenderbufferParameteriv = qglfResolveGetRenderbufferParameteriv;
+}
+
+static void qglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getShaderiv = (type_glGetShaderiv)
+ context->getProcAddress(QLatin1String("glGetShaderiv"));
+ if (!funcs->getShaderiv) {
+ funcs->getShaderiv = (type_glGetShaderiv)
+ context->getProcAddress(QLatin1String("glGetObjectParameterivARB"));
+ }
+
+ if (funcs->getShaderiv)
+ funcs->getShaderiv(shader, pname, params);
+ else
+ funcs->getShaderiv = qglfResolveGetShaderiv;
+}
+
+static void qglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+ typedef void (QGLF_APIENTRYP type_glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getShaderInfoLog = (type_glGetShaderInfoLog)
+ context->getProcAddress(QLatin1String("glGetShaderInfoLog"));
+ if (!funcs->getShaderInfoLog) {
+ funcs->getShaderInfoLog = (type_glGetShaderInfoLog)
+ context->getProcAddress(QLatin1String("glGetInfoLogARB"));
+ }
+
+ if (funcs->getShaderInfoLog)
+ funcs->getShaderInfoLog(shader, bufsize, length, infolog);
+ else
+ funcs->getShaderInfoLog = qglfResolveGetShaderInfoLog;
+}
+
+static void qglfSpecialGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ Q_UNUSED(shadertype);
+ Q_UNUSED(precisiontype);
+ range[0] = range[1] = precision[0] = 0;
+}
+
+static void qglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ typedef void (QGLF_APIENTRYP type_glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getShaderPrecisionFormat = (type_glGetShaderPrecisionFormat)
+ context->getProcAddress(QLatin1String("glGetShaderPrecisionFormat"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->getShaderPrecisionFormat) {
+ funcs->getShaderPrecisionFormat = (type_glGetShaderPrecisionFormat)
+ context->getProcAddress(QLatin1String("glGetShaderPrecisionFormatOES"));
+ }
+#endif
+ if (!funcs->getShaderPrecisionFormat) {
+ funcs->getShaderPrecisionFormat = (type_glGetShaderPrecisionFormat)
+ context->getProcAddress(QLatin1String("glGetShaderPrecisionFormatEXT"));
+ }
+ if (!funcs->getShaderPrecisionFormat) {
+ funcs->getShaderPrecisionFormat = (type_glGetShaderPrecisionFormat)
+ context->getProcAddress(QLatin1String("glGetShaderPrecisionFormatARB"));
+ }
+
+ if (!funcs->getShaderPrecisionFormat)
+ funcs->getShaderPrecisionFormat = qglfSpecialGetShaderPrecisionFormat;
+
+ funcs->getShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+}
+
+static void qglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+{
+ typedef void (QGLF_APIENTRYP type_glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getShaderSource = (type_glGetShaderSource)
+ context->getProcAddress(QLatin1String("glGetShaderSource"));
+ if (!funcs->getShaderSource) {
+ funcs->getShaderSource = (type_glGetShaderSource)
+ context->getProcAddress(QLatin1String("glGetShaderSourceARB"));
+ }
+
+ if (funcs->getShaderSource)
+ funcs->getShaderSource(shader, bufsize, length, source);
+ else
+ funcs->getShaderSource = qglfResolveGetShaderSource;
+}
+
+static void qglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetUniformfv)(GLuint program, GLint location, GLfloat* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getUniformfv = (type_glGetUniformfv)
+ context->getProcAddress(QLatin1String("glGetUniformfv"));
+ if (!funcs->getUniformfv) {
+ funcs->getUniformfv = (type_glGetUniformfv)
+ context->getProcAddress(QLatin1String("glGetUniformfvARB"));
+ }
+
+ if (funcs->getUniformfv)
+ funcs->getUniformfv(program, location, params);
+ else
+ funcs->getUniformfv = qglfResolveGetUniformfv;
+}
+
+static void qglfResolveGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetUniformiv)(GLuint program, GLint location, GLint* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getUniformiv = (type_glGetUniformiv)
+ context->getProcAddress(QLatin1String("glGetUniformiv"));
+ if (!funcs->getUniformiv) {
+ funcs->getUniformiv = (type_glGetUniformiv)
+ context->getProcAddress(QLatin1String("glGetUniformivARB"));
+ }
+
+ if (funcs->getUniformiv)
+ funcs->getUniformiv(program, location, params);
+ else
+ funcs->getUniformiv = qglfResolveGetUniformiv;
+}
+
+static int qglfResolveGetUniformLocation(GLuint program, const char* name)
+{
+ typedef int (QGLF_APIENTRYP type_glGetUniformLocation)(GLuint program, const char* name);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getUniformLocation = (type_glGetUniformLocation)
+ context->getProcAddress(QLatin1String("glGetUniformLocation"));
+ if (!funcs->getUniformLocation) {
+ funcs->getUniformLocation = (type_glGetUniformLocation)
+ context->getProcAddress(QLatin1String("glGetUniformLocationARB"));
+ }
+
+ if (funcs->getUniformLocation)
+ return funcs->getUniformLocation(program, name);
+ funcs->getUniformLocation = qglfResolveGetUniformLocation;
+ return int(0);
+}
+
+static void qglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getVertexAttribfv = (type_glGetVertexAttribfv)
+ context->getProcAddress(QLatin1String("glGetVertexAttribfv"));
+ if (!funcs->getVertexAttribfv) {
+ funcs->getVertexAttribfv = (type_glGetVertexAttribfv)
+ context->getProcAddress(QLatin1String("glGetVertexAttribfvARB"));
+ }
+
+ if (funcs->getVertexAttribfv)
+ funcs->getVertexAttribfv(index, pname, params);
+ else
+ funcs->getVertexAttribfv = qglfResolveGetVertexAttribfv;
+}
+
+static void qglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+ typedef void (QGLF_APIENTRYP type_glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getVertexAttribiv = (type_glGetVertexAttribiv)
+ context->getProcAddress(QLatin1String("glGetVertexAttribiv"));
+ if (!funcs->getVertexAttribiv) {
+ funcs->getVertexAttribiv = (type_glGetVertexAttribiv)
+ context->getProcAddress(QLatin1String("glGetVertexAttribivARB"));
+ }
+
+ if (funcs->getVertexAttribiv)
+ funcs->getVertexAttribiv(index, pname, params);
+ else
+ funcs->getVertexAttribiv = qglfResolveGetVertexAttribiv;
+}
+
+static void qglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
+{
+ typedef void (QGLF_APIENTRYP type_glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->getVertexAttribPointerv = (type_glGetVertexAttribPointerv)
+ context->getProcAddress(QLatin1String("glGetVertexAttribPointerv"));
+ if (!funcs->getVertexAttribPointerv) {
+ funcs->getVertexAttribPointerv = (type_glGetVertexAttribPointerv)
+ context->getProcAddress(QLatin1String("glGetVertexAttribPointervARB"));
+ }
+
+ if (funcs->getVertexAttribPointerv)
+ funcs->getVertexAttribPointerv(index, pname, pointer);
+ else
+ funcs->getVertexAttribPointerv = qglfResolveGetVertexAttribPointerv;
+}
+
+static GLboolean qglfResolveIsBuffer(GLuint buffer)
+{
+ typedef GLboolean (QGLF_APIENTRYP type_glIsBuffer)(GLuint buffer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->isBuffer = (type_glIsBuffer)
+ context->getProcAddress(QLatin1String("glIsBuffer"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->isBuffer) {
+ funcs->isBuffer = (type_glIsBuffer)
+ context->getProcAddress(QLatin1String("glIsBufferOES"));
+ }
+#endif
+ if (!funcs->isBuffer) {
+ funcs->isBuffer = (type_glIsBuffer)
+ context->getProcAddress(QLatin1String("glIsBufferEXT"));
+ }
+ if (!funcs->isBuffer) {
+ funcs->isBuffer = (type_glIsBuffer)
+ context->getProcAddress(QLatin1String("glIsBufferARB"));
+ }
+
+ if (funcs->isBuffer)
+ return funcs->isBuffer(buffer);
+ funcs->isBuffer = qglfResolveIsBuffer;
+ return GLboolean(0);
+}
+
+static GLboolean qglfResolveIsFramebuffer(GLuint framebuffer)
+{
+ typedef GLboolean (QGLF_APIENTRYP type_glIsFramebuffer)(GLuint framebuffer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->isFramebuffer = (type_glIsFramebuffer)
+ context->getProcAddress(QLatin1String("glIsFramebuffer"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->isFramebuffer) {
+ funcs->isFramebuffer = (type_glIsFramebuffer)
+ context->getProcAddress(QLatin1String("glIsFramebufferOES"));
+ }
+#endif
+ if (!funcs->isFramebuffer) {
+ funcs->isFramebuffer = (type_glIsFramebuffer)
+ context->getProcAddress(QLatin1String("glIsFramebufferEXT"));
+ }
+ if (!funcs->isFramebuffer) {
+ funcs->isFramebuffer = (type_glIsFramebuffer)
+ context->getProcAddress(QLatin1String("glIsFramebufferARB"));
+ }
+
+ if (funcs->isFramebuffer)
+ return funcs->isFramebuffer(framebuffer);
+ funcs->isFramebuffer = qglfResolveIsFramebuffer;
+ return GLboolean(0);
+}
+
+static GLboolean qglfSpecialIsProgram(GLuint program)
+{
+ return program != 0;
+}
+
+static GLboolean qglfResolveIsProgram(GLuint program)
+{
+ typedef GLboolean (QGLF_APIENTRYP type_glIsProgram)(GLuint program);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->isProgram = (type_glIsProgram)
+ context->getProcAddress(QLatin1String("glIsProgram"));
+ if (!funcs->isProgram) {
+ funcs->isProgram = (type_glIsProgram)
+ context->getProcAddress(QLatin1String("glIsProgramARB"));
+ }
+
+ if (!funcs->isProgram)
+ funcs->isProgram = qglfSpecialIsProgram;
+
+ return funcs->isProgram(program);
+}
+
+static GLboolean qglfResolveIsRenderbuffer(GLuint renderbuffer)
+{
+ typedef GLboolean (QGLF_APIENTRYP type_glIsRenderbuffer)(GLuint renderbuffer);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->isRenderbuffer = (type_glIsRenderbuffer)
+ context->getProcAddress(QLatin1String("glIsRenderbuffer"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->isRenderbuffer) {
+ funcs->isRenderbuffer = (type_glIsRenderbuffer)
+ context->getProcAddress(QLatin1String("glIsRenderbufferOES"));
+ }
+#endif
+ if (!funcs->isRenderbuffer) {
+ funcs->isRenderbuffer = (type_glIsRenderbuffer)
+ context->getProcAddress(QLatin1String("glIsRenderbufferEXT"));
+ }
+ if (!funcs->isRenderbuffer) {
+ funcs->isRenderbuffer = (type_glIsRenderbuffer)
+ context->getProcAddress(QLatin1String("glIsRenderbufferARB"));
+ }
+
+ if (funcs->isRenderbuffer)
+ return funcs->isRenderbuffer(renderbuffer);
+ funcs->isRenderbuffer = qglfResolveIsRenderbuffer;
+ return GLboolean(0);
+}
+
+static GLboolean qglfSpecialIsShader(GLuint shader)
+{
+ return shader != 0;
+}
+
+static GLboolean qglfResolveIsShader(GLuint shader)
+{
+ typedef GLboolean (QGLF_APIENTRYP type_glIsShader)(GLuint shader);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->isShader = (type_glIsShader)
+ context->getProcAddress(QLatin1String("glIsShader"));
+ if (!funcs->isShader) {
+ funcs->isShader = (type_glIsShader)
+ context->getProcAddress(QLatin1String("glIsShaderARB"));
+ }
+
+ if (!funcs->isShader)
+ funcs->isShader = qglfSpecialIsShader;
+
+ return funcs->isShader(shader);
+}
+
+static void qglfResolveLinkProgram(GLuint program)
+{
+ typedef void (QGLF_APIENTRYP type_glLinkProgram)(GLuint program);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->linkProgram = (type_glLinkProgram)
+ context->getProcAddress(QLatin1String("glLinkProgram"));
+ if (!funcs->linkProgram) {
+ funcs->linkProgram = (type_glLinkProgram)
+ context->getProcAddress(QLatin1String("glLinkProgramARB"));
+ }
+
+ if (funcs->linkProgram)
+ funcs->linkProgram(program);
+ else
+ funcs->linkProgram = qglfResolveLinkProgram;
+}
+
+static void qglfSpecialReleaseShaderCompiler()
+{
+}
+
+static void qglfResolveReleaseShaderCompiler()
+{
+ typedef void (QGLF_APIENTRYP type_glReleaseShaderCompiler)();
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->releaseShaderCompiler = (type_glReleaseShaderCompiler)
+ context->getProcAddress(QLatin1String("glReleaseShaderCompiler"));
+ if (!funcs->releaseShaderCompiler) {
+ funcs->releaseShaderCompiler = (type_glReleaseShaderCompiler)
+ context->getProcAddress(QLatin1String("glReleaseShaderCompilerARB"));
+ }
+
+ if (!funcs->releaseShaderCompiler)
+ funcs->releaseShaderCompiler = qglfSpecialReleaseShaderCompiler;
+
+ funcs->releaseShaderCompiler();
+}
+
+static void qglfResolveRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ typedef void (QGLF_APIENTRYP type_glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->renderbufferStorage = (type_glRenderbufferStorage)
+ context->getProcAddress(QLatin1String("glRenderbufferStorage"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->renderbufferStorage) {
+ funcs->renderbufferStorage = (type_glRenderbufferStorage)
+ context->getProcAddress(QLatin1String("glRenderbufferStorageOES"));
+ }
+#endif
+ if (!funcs->renderbufferStorage) {
+ funcs->renderbufferStorage = (type_glRenderbufferStorage)
+ context->getProcAddress(QLatin1String("glRenderbufferStorageEXT"));
+ }
+ if (!funcs->renderbufferStorage) {
+ funcs->renderbufferStorage = (type_glRenderbufferStorage)
+ context->getProcAddress(QLatin1String("glRenderbufferStorageARB"));
+ }
+
+ if (funcs->renderbufferStorage)
+ funcs->renderbufferStorage(target, internalformat, width, height);
+ else
+ funcs->renderbufferStorage = qglfResolveRenderbufferStorage;
+}
+
+static void qglfResolveSampleCoverage(GLclampf value, GLboolean invert)
+{
+ typedef void (QGLF_APIENTRYP type_glSampleCoverage)(GLclampf value, GLboolean invert);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->sampleCoverage = (type_glSampleCoverage)
+ context->getProcAddress(QLatin1String("glSampleCoverage"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->sampleCoverage) {
+ funcs->sampleCoverage = (type_glSampleCoverage)
+ context->getProcAddress(QLatin1String("glSampleCoverageOES"));
+ }
+#endif
+ if (!funcs->sampleCoverage) {
+ funcs->sampleCoverage = (type_glSampleCoverage)
+ context->getProcAddress(QLatin1String("glSampleCoverageEXT"));
+ }
+ if (!funcs->sampleCoverage) {
+ funcs->sampleCoverage = (type_glSampleCoverage)
+ context->getProcAddress(QLatin1String("glSampleCoverageARB"));
+ }
+
+ if (funcs->sampleCoverage)
+ funcs->sampleCoverage(value, invert);
+ else
+ funcs->sampleCoverage = qglfResolveSampleCoverage;
+}
+
+static void qglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
+{
+ typedef void (QGLF_APIENTRYP type_glShaderBinary)(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->shaderBinary = (type_glShaderBinary)
+ context->getProcAddress(QLatin1String("glShaderBinary"));
+ if (!funcs->shaderBinary) {
+ funcs->shaderBinary = (type_glShaderBinary)
+ context->getProcAddress(QLatin1String("glShaderBinaryARB"));
+ }
+
+ if (funcs->shaderBinary)
+ funcs->shaderBinary(n, shaders, binaryformat, binary, length);
+ else
+ funcs->shaderBinary = qglfResolveShaderBinary;
+}
+
+static void qglfResolveShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+{
+ typedef void (QGLF_APIENTRYP type_glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->shaderSource = (type_glShaderSource)
+ context->getProcAddress(QLatin1String("glShaderSource"));
+ if (!funcs->shaderSource) {
+ funcs->shaderSource = (type_glShaderSource)
+ context->getProcAddress(QLatin1String("glShaderSourceARB"));
+ }
+
+ if (funcs->shaderSource)
+ funcs->shaderSource(shader, count, string, length);
+ else
+ funcs->shaderSource = qglfResolveShaderSource;
+}
+
+static void qglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ typedef void (QGLF_APIENTRYP type_glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->stencilFuncSeparate = (type_glStencilFuncSeparate)
+ context->getProcAddress(QLatin1String("glStencilFuncSeparate"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->stencilFuncSeparate) {
+ funcs->stencilFuncSeparate = (type_glStencilFuncSeparate)
+ context->getProcAddress(QLatin1String("glStencilFuncSeparateOES"));
+ }
+#endif
+ if (!funcs->stencilFuncSeparate) {
+ funcs->stencilFuncSeparate = (type_glStencilFuncSeparate)
+ context->getProcAddress(QLatin1String("glStencilFuncSeparateEXT"));
+ }
+ if (!funcs->stencilFuncSeparate) {
+ funcs->stencilFuncSeparate = (type_glStencilFuncSeparate)
+ context->getProcAddress(QLatin1String("glStencilFuncSeparateARB"));
+ }
+
+ if (funcs->stencilFuncSeparate)
+ funcs->stencilFuncSeparate(face, func, ref, mask);
+ else
+ funcs->stencilFuncSeparate = qglfResolveStencilFuncSeparate;
+}
+
+static void qglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
+{
+ typedef void (QGLF_APIENTRYP type_glStencilMaskSeparate)(GLenum face, GLuint mask);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->stencilMaskSeparate = (type_glStencilMaskSeparate)
+ context->getProcAddress(QLatin1String("glStencilMaskSeparate"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->stencilMaskSeparate) {
+ funcs->stencilMaskSeparate = (type_glStencilMaskSeparate)
+ context->getProcAddress(QLatin1String("glStencilMaskSeparateOES"));
+ }
+#endif
+ if (!funcs->stencilMaskSeparate) {
+ funcs->stencilMaskSeparate = (type_glStencilMaskSeparate)
+ context->getProcAddress(QLatin1String("glStencilMaskSeparateEXT"));
+ }
+ if (!funcs->stencilMaskSeparate) {
+ funcs->stencilMaskSeparate = (type_glStencilMaskSeparate)
+ context->getProcAddress(QLatin1String("glStencilMaskSeparateARB"));
+ }
+
+ if (funcs->stencilMaskSeparate)
+ funcs->stencilMaskSeparate(face, mask);
+ else
+ funcs->stencilMaskSeparate = qglfResolveStencilMaskSeparate;
+}
+
+static void qglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ typedef void (QGLF_APIENTRYP type_glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->stencilOpSeparate = (type_glStencilOpSeparate)
+ context->getProcAddress(QLatin1String("glStencilOpSeparate"));
+#ifdef QT_OPENGL_ES
+ if (!funcs->stencilOpSeparate) {
+ funcs->stencilOpSeparate = (type_glStencilOpSeparate)
+ context->getProcAddress(QLatin1String("glStencilOpSeparateOES"));
+ }
+#endif
+ if (!funcs->stencilOpSeparate) {
+ funcs->stencilOpSeparate = (type_glStencilOpSeparate)
+ context->getProcAddress(QLatin1String("glStencilOpSeparateEXT"));
+ }
+ if (!funcs->stencilOpSeparate) {
+ funcs->stencilOpSeparate = (type_glStencilOpSeparate)
+ context->getProcAddress(QLatin1String("glStencilOpSeparateARB"));
+ }
+
+ if (funcs->stencilOpSeparate)
+ funcs->stencilOpSeparate(face, fail, zfail, zpass);
+ else
+ funcs->stencilOpSeparate = qglfResolveStencilOpSeparate;
+}
+
+static void qglfResolveUniform1f(GLint location, GLfloat x)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform1f)(GLint location, GLfloat x);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform1f = (type_glUniform1f)
+ context->getProcAddress(QLatin1String("glUniform1f"));
+ if (!funcs->uniform1f) {
+ funcs->uniform1f = (type_glUniform1f)
+ context->getProcAddress(QLatin1String("glUniform1fARB"));
+ }
+
+ if (funcs->uniform1f)
+ funcs->uniform1f(location, x);
+ else
+ funcs->uniform1f = qglfResolveUniform1f;
+}
+
+static void qglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform1fv)(GLint location, GLsizei count, const GLfloat* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform1fv = (type_glUniform1fv)
+ context->getProcAddress(QLatin1String("glUniform1fv"));
+ if (!funcs->uniform1fv) {
+ funcs->uniform1fv = (type_glUniform1fv)
+ context->getProcAddress(QLatin1String("glUniform1fvARB"));
+ }
+
+ if (funcs->uniform1fv)
+ funcs->uniform1fv(location, count, v);
+ else
+ funcs->uniform1fv = qglfResolveUniform1fv;
+}
+
+static void qglfResolveUniform1i(GLint location, GLint x)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform1i)(GLint location, GLint x);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform1i = (type_glUniform1i)
+ context->getProcAddress(QLatin1String("glUniform1i"));
+ if (!funcs->uniform1i) {
+ funcs->uniform1i = (type_glUniform1i)
+ context->getProcAddress(QLatin1String("glUniform1iARB"));
+ }
+
+ if (funcs->uniform1i)
+ funcs->uniform1i(location, x);
+ else
+ funcs->uniform1i = qglfResolveUniform1i;
+}
+
+static void qglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform1iv)(GLint location, GLsizei count, const GLint* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform1iv = (type_glUniform1iv)
+ context->getProcAddress(QLatin1String("glUniform1iv"));
+ if (!funcs->uniform1iv) {
+ funcs->uniform1iv = (type_glUniform1iv)
+ context->getProcAddress(QLatin1String("glUniform1ivARB"));
+ }
+
+ if (funcs->uniform1iv)
+ funcs->uniform1iv(location, count, v);
+ else
+ funcs->uniform1iv = qglfResolveUniform1iv;
+}
+
+static void qglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform2f)(GLint location, GLfloat x, GLfloat y);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform2f = (type_glUniform2f)
+ context->getProcAddress(QLatin1String("glUniform2f"));
+ if (!funcs->uniform2f) {
+ funcs->uniform2f = (type_glUniform2f)
+ context->getProcAddress(QLatin1String("glUniform2fARB"));
+ }
+
+ if (funcs->uniform2f)
+ funcs->uniform2f(location, x, y);
+ else
+ funcs->uniform2f = qglfResolveUniform2f;
+}
+
+static void qglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform2fv)(GLint location, GLsizei count, const GLfloat* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform2fv = (type_glUniform2fv)
+ context->getProcAddress(QLatin1String("glUniform2fv"));
+ if (!funcs->uniform2fv) {
+ funcs->uniform2fv = (type_glUniform2fv)
+ context->getProcAddress(QLatin1String("glUniform2fvARB"));
+ }
+
+ if (funcs->uniform2fv)
+ funcs->uniform2fv(location, count, v);
+ else
+ funcs->uniform2fv = qglfResolveUniform2fv;
+}
+
+static void qglfResolveUniform2i(GLint location, GLint x, GLint y)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform2i)(GLint location, GLint x, GLint y);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform2i = (type_glUniform2i)
+ context->getProcAddress(QLatin1String("glUniform2i"));
+ if (!funcs->uniform2i) {
+ funcs->uniform2i = (type_glUniform2i)
+ context->getProcAddress(QLatin1String("glUniform2iARB"));
+ }
+
+ if (funcs->uniform2i)
+ funcs->uniform2i(location, x, y);
+ else
+ funcs->uniform2i = qglfResolveUniform2i;
+}
+
+static void qglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform2iv)(GLint location, GLsizei count, const GLint* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform2iv = (type_glUniform2iv)
+ context->getProcAddress(QLatin1String("glUniform2iv"));
+ if (!funcs->uniform2iv) {
+ funcs->uniform2iv = (type_glUniform2iv)
+ context->getProcAddress(QLatin1String("glUniform2ivARB"));
+ }
+
+ if (funcs->uniform2iv)
+ funcs->uniform2iv(location, count, v);
+ else
+ funcs->uniform2iv = qglfResolveUniform2iv;
+}
+
+static void qglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform3f = (type_glUniform3f)
+ context->getProcAddress(QLatin1String("glUniform3f"));
+ if (!funcs->uniform3f) {
+ funcs->uniform3f = (type_glUniform3f)
+ context->getProcAddress(QLatin1String("glUniform3fARB"));
+ }
+
+ if (funcs->uniform3f)
+ funcs->uniform3f(location, x, y, z);
+ else
+ funcs->uniform3f = qglfResolveUniform3f;
+}
+
+static void qglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform3fv)(GLint location, GLsizei count, const GLfloat* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform3fv = (type_glUniform3fv)
+ context->getProcAddress(QLatin1String("glUniform3fv"));
+ if (!funcs->uniform3fv) {
+ funcs->uniform3fv = (type_glUniform3fv)
+ context->getProcAddress(QLatin1String("glUniform3fvARB"));
+ }
+
+ if (funcs->uniform3fv)
+ funcs->uniform3fv(location, count, v);
+ else
+ funcs->uniform3fv = qglfResolveUniform3fv;
+}
+
+static void qglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform3i)(GLint location, GLint x, GLint y, GLint z);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform3i = (type_glUniform3i)
+ context->getProcAddress(QLatin1String("glUniform3i"));
+ if (!funcs->uniform3i) {
+ funcs->uniform3i = (type_glUniform3i)
+ context->getProcAddress(QLatin1String("glUniform3iARB"));
+ }
+
+ if (funcs->uniform3i)
+ funcs->uniform3i(location, x, y, z);
+ else
+ funcs->uniform3i = qglfResolveUniform3i;
+}
+
+static void qglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform3iv)(GLint location, GLsizei count, const GLint* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform3iv = (type_glUniform3iv)
+ context->getProcAddress(QLatin1String("glUniform3iv"));
+ if (!funcs->uniform3iv) {
+ funcs->uniform3iv = (type_glUniform3iv)
+ context->getProcAddress(QLatin1String("glUniform3ivARB"));
+ }
+
+ if (funcs->uniform3iv)
+ funcs->uniform3iv(location, count, v);
+ else
+ funcs->uniform3iv = qglfResolveUniform3iv;
+}
+
+static void qglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform4f = (type_glUniform4f)
+ context->getProcAddress(QLatin1String("glUniform4f"));
+ if (!funcs->uniform4f) {
+ funcs->uniform4f = (type_glUniform4f)
+ context->getProcAddress(QLatin1String("glUniform4fARB"));
+ }
+
+ if (funcs->uniform4f)
+ funcs->uniform4f(location, x, y, z, w);
+ else
+ funcs->uniform4f = qglfResolveUniform4f;
+}
+
+static void qglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform4fv)(GLint location, GLsizei count, const GLfloat* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform4fv = (type_glUniform4fv)
+ context->getProcAddress(QLatin1String("glUniform4fv"));
+ if (!funcs->uniform4fv) {
+ funcs->uniform4fv = (type_glUniform4fv)
+ context->getProcAddress(QLatin1String("glUniform4fvARB"));
+ }
+
+ if (funcs->uniform4fv)
+ funcs->uniform4fv(location, count, v);
+ else
+ funcs->uniform4fv = qglfResolveUniform4fv;
+}
+
+static void qglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform4i = (type_glUniform4i)
+ context->getProcAddress(QLatin1String("glUniform4i"));
+ if (!funcs->uniform4i) {
+ funcs->uniform4i = (type_glUniform4i)
+ context->getProcAddress(QLatin1String("glUniform4iARB"));
+ }
+
+ if (funcs->uniform4i)
+ funcs->uniform4i(location, x, y, z, w);
+ else
+ funcs->uniform4i = qglfResolveUniform4i;
+}
+
+static void qglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+ typedef void (QGLF_APIENTRYP type_glUniform4iv)(GLint location, GLsizei count, const GLint* v);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniform4iv = (type_glUniform4iv)
+ context->getProcAddress(QLatin1String("glUniform4iv"));
+ if (!funcs->uniform4iv) {
+ funcs->uniform4iv = (type_glUniform4iv)
+ context->getProcAddress(QLatin1String("glUniform4ivARB"));
+ }
+
+ if (funcs->uniform4iv)
+ funcs->uniform4iv(location, count, v);
+ else
+ funcs->uniform4iv = qglfResolveUniform4iv;
+}
+
+static void qglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ typedef void (QGLF_APIENTRYP type_glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniformMatrix2fv = (type_glUniformMatrix2fv)
+ context->getProcAddress(QLatin1String("glUniformMatrix2fv"));
+ if (!funcs->uniformMatrix2fv) {
+ funcs->uniformMatrix2fv = (type_glUniformMatrix2fv)
+ context->getProcAddress(QLatin1String("glUniformMatrix2fvARB"));
+ }
+
+ if (funcs->uniformMatrix2fv)
+ funcs->uniformMatrix2fv(location, count, transpose, value);
+ else
+ funcs->uniformMatrix2fv = qglfResolveUniformMatrix2fv;
+}
+
+static void qglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ typedef void (QGLF_APIENTRYP type_glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniformMatrix3fv = (type_glUniformMatrix3fv)
+ context->getProcAddress(QLatin1String("glUniformMatrix3fv"));
+ if (!funcs->uniformMatrix3fv) {
+ funcs->uniformMatrix3fv = (type_glUniformMatrix3fv)
+ context->getProcAddress(QLatin1String("glUniformMatrix3fvARB"));
+ }
+
+ if (funcs->uniformMatrix3fv)
+ funcs->uniformMatrix3fv(location, count, transpose, value);
+ else
+ funcs->uniformMatrix3fv = qglfResolveUniformMatrix3fv;
+}
+
+static void qglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ typedef void (QGLF_APIENTRYP type_glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->uniformMatrix4fv = (type_glUniformMatrix4fv)
+ context->getProcAddress(QLatin1String("glUniformMatrix4fv"));
+ if (!funcs->uniformMatrix4fv) {
+ funcs->uniformMatrix4fv = (type_glUniformMatrix4fv)
+ context->getProcAddress(QLatin1String("glUniformMatrix4fvARB"));
+ }
+
+ if (funcs->uniformMatrix4fv)
+ funcs->uniformMatrix4fv(location, count, transpose, value);
+ else
+ funcs->uniformMatrix4fv = qglfResolveUniformMatrix4fv;
+}
+
+static void qglfResolveUseProgram(GLuint program)
+{
+ typedef void (QGLF_APIENTRYP type_glUseProgram)(GLuint program);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->useProgram = (type_glUseProgram)
+ context->getProcAddress(QLatin1String("glUseProgram"));
+ if (!funcs->useProgram) {
+ funcs->useProgram = (type_glUseProgram)
+ context->getProcAddress(QLatin1String("glUseProgramObjectARB"));
+ }
+
+ if (funcs->useProgram)
+ funcs->useProgram(program);
+ else
+ funcs->useProgram = qglfResolveUseProgram;
+}
+
+static void qglfResolveValidateProgram(GLuint program)
+{
+ typedef void (QGLF_APIENTRYP type_glValidateProgram)(GLuint program);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->validateProgram = (type_glValidateProgram)
+ context->getProcAddress(QLatin1String("glValidateProgram"));
+ if (!funcs->validateProgram) {
+ funcs->validateProgram = (type_glValidateProgram)
+ context->getProcAddress(QLatin1String("glValidateProgramARB"));
+ }
+
+ if (funcs->validateProgram)
+ funcs->validateProgram(program);
+ else
+ funcs->validateProgram = qglfResolveValidateProgram;
+}
+
+static void qglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib1f)(GLuint indx, GLfloat x);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib1f = (type_glVertexAttrib1f)
+ context->getProcAddress(QLatin1String("glVertexAttrib1f"));
+ if (!funcs->vertexAttrib1f) {
+ funcs->vertexAttrib1f = (type_glVertexAttrib1f)
+ context->getProcAddress(QLatin1String("glVertexAttrib1fARB"));
+ }
+
+ if (funcs->vertexAttrib1f)
+ funcs->vertexAttrib1f(indx, x);
+ else
+ funcs->vertexAttrib1f = qglfResolveVertexAttrib1f;
+}
+
+static void qglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib1fv)(GLuint indx, const GLfloat* values);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib1fv = (type_glVertexAttrib1fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib1fv"));
+ if (!funcs->vertexAttrib1fv) {
+ funcs->vertexAttrib1fv = (type_glVertexAttrib1fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib1fvARB"));
+ }
+
+ if (funcs->vertexAttrib1fv)
+ funcs->vertexAttrib1fv(indx, values);
+ else
+ funcs->vertexAttrib1fv = qglfResolveVertexAttrib1fv;
+}
+
+static void qglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib2f = (type_glVertexAttrib2f)
+ context->getProcAddress(QLatin1String("glVertexAttrib2f"));
+ if (!funcs->vertexAttrib2f) {
+ funcs->vertexAttrib2f = (type_glVertexAttrib2f)
+ context->getProcAddress(QLatin1String("glVertexAttrib2fARB"));
+ }
+
+ if (funcs->vertexAttrib2f)
+ funcs->vertexAttrib2f(indx, x, y);
+ else
+ funcs->vertexAttrib2f = qglfResolveVertexAttrib2f;
+}
+
+static void qglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib2fv)(GLuint indx, const GLfloat* values);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib2fv = (type_glVertexAttrib2fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib2fv"));
+ if (!funcs->vertexAttrib2fv) {
+ funcs->vertexAttrib2fv = (type_glVertexAttrib2fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib2fvARB"));
+ }
+
+ if (funcs->vertexAttrib2fv)
+ funcs->vertexAttrib2fv(indx, values);
+ else
+ funcs->vertexAttrib2fv = qglfResolveVertexAttrib2fv;
+}
+
+static void qglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib3f = (type_glVertexAttrib3f)
+ context->getProcAddress(QLatin1String("glVertexAttrib3f"));
+ if (!funcs->vertexAttrib3f) {
+ funcs->vertexAttrib3f = (type_glVertexAttrib3f)
+ context->getProcAddress(QLatin1String("glVertexAttrib3fARB"));
+ }
+
+ if (funcs->vertexAttrib3f)
+ funcs->vertexAttrib3f(indx, x, y, z);
+ else
+ funcs->vertexAttrib3f = qglfResolveVertexAttrib3f;
+}
+
+static void qglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib3fv)(GLuint indx, const GLfloat* values);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib3fv = (type_glVertexAttrib3fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib3fv"));
+ if (!funcs->vertexAttrib3fv) {
+ funcs->vertexAttrib3fv = (type_glVertexAttrib3fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib3fvARB"));
+ }
+
+ if (funcs->vertexAttrib3fv)
+ funcs->vertexAttrib3fv(indx, values);
+ else
+ funcs->vertexAttrib3fv = qglfResolveVertexAttrib3fv;
+}
+
+static void qglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib4f = (type_glVertexAttrib4f)
+ context->getProcAddress(QLatin1String("glVertexAttrib4f"));
+ if (!funcs->vertexAttrib4f) {
+ funcs->vertexAttrib4f = (type_glVertexAttrib4f)
+ context->getProcAddress(QLatin1String("glVertexAttrib4fARB"));
+ }
+
+ if (funcs->vertexAttrib4f)
+ funcs->vertexAttrib4f(indx, x, y, z, w);
+ else
+ funcs->vertexAttrib4f = qglfResolveVertexAttrib4f;
+}
+
+static void qglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttrib4fv)(GLuint indx, const GLfloat* values);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttrib4fv = (type_glVertexAttrib4fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib4fv"));
+ if (!funcs->vertexAttrib4fv) {
+ funcs->vertexAttrib4fv = (type_glVertexAttrib4fv)
+ context->getProcAddress(QLatin1String("glVertexAttrib4fvARB"));
+ }
+
+ if (funcs->vertexAttrib4fv)
+ funcs->vertexAttrib4fv(indx, values);
+ else
+ funcs->vertexAttrib4fv = qglfResolveVertexAttrib4fv;
+}
+
+static void qglfResolveVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+{
+ typedef void (QGLF_APIENTRYP type_glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+
+ const QGLContext *context = QGLContext::currentContext();
+ QGLFunctionsPrivate *funcs = qt_gl_functions(context);
+
+ funcs->vertexAttribPointer = (type_glVertexAttribPointer)
+ context->getProcAddress(QLatin1String("glVertexAttribPointer"));
+ if (!funcs->vertexAttribPointer) {
+ funcs->vertexAttribPointer = (type_glVertexAttribPointer)
+ context->getProcAddress(QLatin1String("glVertexAttribPointerARB"));
+ }
+
+ if (funcs->vertexAttribPointer)
+ funcs->vertexAttribPointer(indx, size, type, normalized, stride, ptr);
+ else
+ funcs->vertexAttribPointer = qglfResolveVertexAttribPointer;
+}
+
+#endif // !QT_OPENGL_ES_2
+
+QGLFunctionsPrivate::QGLFunctionsPrivate(const QGLContext *)
+{
+#ifndef QT_OPENGL_ES_2
+ activeTexture = qglfResolveActiveTexture;
+ attachShader = qglfResolveAttachShader;
+ bindAttribLocation = qglfResolveBindAttribLocation;
+ bindBuffer = qglfResolveBindBuffer;
+ bindFramebuffer = qglfResolveBindFramebuffer;
+ bindRenderbuffer = qglfResolveBindRenderbuffer;
+ blendColor = qglfResolveBlendColor;
+ blendEquation = qglfResolveBlendEquation;
+ blendEquationSeparate = qglfResolveBlendEquationSeparate;
+ blendFuncSeparate = qglfResolveBlendFuncSeparate;
+ bufferData = qglfResolveBufferData;
+ bufferSubData = qglfResolveBufferSubData;
+ checkFramebufferStatus = qglfResolveCheckFramebufferStatus;
+ compileShader = qglfResolveCompileShader;
+ compressedTexImage2D = qglfResolveCompressedTexImage2D;
+ compressedTexSubImage2D = qglfResolveCompressedTexSubImage2D;
+ createProgram = qglfResolveCreateProgram;
+ createShader = qglfResolveCreateShader;
+ deleteBuffers = qglfResolveDeleteBuffers;
+ deleteFramebuffers = qglfResolveDeleteFramebuffers;
+ deleteProgram = qglfResolveDeleteProgram;
+ deleteRenderbuffers = qglfResolveDeleteRenderbuffers;
+ deleteShader = qglfResolveDeleteShader;
+ detachShader = qglfResolveDetachShader;
+ disableVertexAttribArray = qglfResolveDisableVertexAttribArray;
+ enableVertexAttribArray = qglfResolveEnableVertexAttribArray;
+ framebufferRenderbuffer = qglfResolveFramebufferRenderbuffer;
+ framebufferTexture2D = qglfResolveFramebufferTexture2D;
+ genBuffers = qglfResolveGenBuffers;
+ generateMipmap = qglfResolveGenerateMipmap;
+ genFramebuffers = qglfResolveGenFramebuffers;
+ genRenderbuffers = qglfResolveGenRenderbuffers;
+ getActiveAttrib = qglfResolveGetActiveAttrib;
+ getActiveUniform = qglfResolveGetActiveUniform;
+ getAttachedShaders = qglfResolveGetAttachedShaders;
+ getAttribLocation = qglfResolveGetAttribLocation;
+ getBufferParameteriv = qglfResolveGetBufferParameteriv;
+ getFramebufferAttachmentParameteriv = qglfResolveGetFramebufferAttachmentParameteriv;
+ getProgramiv = qglfResolveGetProgramiv;
+ getProgramInfoLog = qglfResolveGetProgramInfoLog;
+ getRenderbufferParameteriv = qglfResolveGetRenderbufferParameteriv;
+ getShaderiv = qglfResolveGetShaderiv;
+ getShaderInfoLog = qglfResolveGetShaderInfoLog;
+ getShaderPrecisionFormat = qglfResolveGetShaderPrecisionFormat;
+ getShaderSource = qglfResolveGetShaderSource;
+ getUniformfv = qglfResolveGetUniformfv;
+ getUniformiv = qglfResolveGetUniformiv;
+ getUniformLocation = qglfResolveGetUniformLocation;
+ getVertexAttribfv = qglfResolveGetVertexAttribfv;
+ getVertexAttribiv = qglfResolveGetVertexAttribiv;
+ getVertexAttribPointerv = qglfResolveGetVertexAttribPointerv;
+ isBuffer = qglfResolveIsBuffer;
+ isFramebuffer = qglfResolveIsFramebuffer;
+ isProgram = qglfResolveIsProgram;
+ isRenderbuffer = qglfResolveIsRenderbuffer;
+ isShader = qglfResolveIsShader;
+ linkProgram = qglfResolveLinkProgram;
+ releaseShaderCompiler = qglfResolveReleaseShaderCompiler;
+ renderbufferStorage = qglfResolveRenderbufferStorage;
+ sampleCoverage = qglfResolveSampleCoverage;
+ shaderBinary = qglfResolveShaderBinary;
+ shaderSource = qglfResolveShaderSource;
+ stencilFuncSeparate = qglfResolveStencilFuncSeparate;
+ stencilMaskSeparate = qglfResolveStencilMaskSeparate;
+ stencilOpSeparate = qglfResolveStencilOpSeparate;
+ uniform1f = qglfResolveUniform1f;
+ uniform1fv = qglfResolveUniform1fv;
+ uniform1i = qglfResolveUniform1i;
+ uniform1iv = qglfResolveUniform1iv;
+ uniform2f = qglfResolveUniform2f;
+ uniform2fv = qglfResolveUniform2fv;
+ uniform2i = qglfResolveUniform2i;
+ uniform2iv = qglfResolveUniform2iv;
+ uniform3f = qglfResolveUniform3f;
+ uniform3fv = qglfResolveUniform3fv;
+ uniform3i = qglfResolveUniform3i;
+ uniform3iv = qglfResolveUniform3iv;
+ uniform4f = qglfResolveUniform4f;
+ uniform4fv = qglfResolveUniform4fv;
+ uniform4i = qglfResolveUniform4i;
+ uniform4iv = qglfResolveUniform4iv;
+ uniformMatrix2fv = qglfResolveUniformMatrix2fv;
+ uniformMatrix3fv = qglfResolveUniformMatrix3fv;
+ uniformMatrix4fv = qglfResolveUniformMatrix4fv;
+ useProgram = qglfResolveUseProgram;
+ validateProgram = qglfResolveValidateProgram;
+ vertexAttrib1f = qglfResolveVertexAttrib1f;
+ vertexAttrib1fv = qglfResolveVertexAttrib1fv;
+ vertexAttrib2f = qglfResolveVertexAttrib2f;
+ vertexAttrib2fv = qglfResolveVertexAttrib2fv;
+ vertexAttrib3f = qglfResolveVertexAttrib3f;
+ vertexAttrib3fv = qglfResolveVertexAttrib3fv;
+ vertexAttrib4f = qglfResolveVertexAttrib4f;
+ vertexAttrib4fv = qglfResolveVertexAttrib4fv;
+ vertexAttribPointer = qglfResolveVertexAttribPointer;
+#endif // !QT_OPENGL_ES_2
+}
+
+QT_END_NAMESPACE
diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h
new file mode 100644
index 0000000000..e06de7fe80
--- /dev/null
+++ b/src/opengl/qglfunctions.h
@@ -0,0 +1,2290 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenGL module 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 QGLFUNCTIONS_H
+#define QGLFUNCTIONS_H
+
+#include <QtOpenGL/qgl.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(OpenGL)
+
+// Types that aren't defined in all system's gl.h files.
+typedef ptrdiff_t qgl_GLintptr;
+typedef ptrdiff_t qgl_GLsizeiptr;
+
+#ifndef Q_WS_MAC
+# ifndef QGLF_APIENTRYP
+# ifdef QGLF_APIENTRY
+# define QGLF_APIENTRYP QGLF_APIENTRY *
+# else
+# define QGLF_APIENTRY
+# define QGLF_APIENTRYP *
+# endif
+# endif
+#else
+# define QGLF_APIENTRY
+# define QGLF_APIENTRYP *
+#endif
+
+struct QGLFunctionsPrivate;
+
+// Undefine any macros from GLEW, qglextensions_p.h, etc that
+// may interfere with the definition of QGLFunctions.
+#undef glActiveTexture
+#undef glAttachShader
+#undef glBindAttribLocation
+#undef glBindBuffer
+#undef glBindFramebuffer
+#undef glBindRenderbuffer
+#undef glBlendColor
+#undef glBlendEquation
+#undef glBlendEquationSeparate
+#undef glBlendFuncSeparate
+#undef glBufferData
+#undef glBufferSubData
+#undef glCheckFramebufferStatus
+#undef glClearDepthf
+#undef glCompileShader
+#undef glCompressedTexImage2D
+#undef glCompressedTexSubImage2D
+#undef glCreateProgram
+#undef glCreateShader
+#undef glDeleteBuffers
+#undef glDeleteFramebuffers
+#undef glDeleteProgram
+#undef glDeleteRenderbuffers
+#undef glDeleteShader
+#undef glDepthRangef
+#undef glDetachShader
+#undef glDisableVertexAttribArray
+#undef glEnableVertexAttribArray
+#undef glFramebufferRenderbuffer
+#undef glFramebufferTexture2D
+#undef glGenBuffers
+#undef glGenerateMipmap
+#undef glGenFramebuffers
+#undef glGenRenderbuffers
+#undef glGetActiveAttrib
+#undef glGetActiveUniform
+#undef glGetAttachedShaders
+#undef glGetAttribLocation
+#undef glGetBufferParameteriv
+#undef glGetFramebufferAttachmentParameteriv
+#undef glGetProgramiv
+#undef glGetProgramInfoLog
+#undef glGetRenderbufferParameteriv
+#undef glGetShaderiv
+#undef glGetShaderInfoLog
+#undef glGetShaderPrecisionFormat
+#undef glGetShaderSource
+#undef glGetUniformfv
+#undef glGetUniformiv
+#undef glGetUniformLocation
+#undef glGetVertexAttribfv
+#undef glGetVertexAttribiv
+#undef glGetVertexAttribPointerv
+#undef glIsBuffer
+#undef glIsFramebuffer
+#undef glIsProgram
+#undef glIsRenderbuffer
+#undef glIsShader
+#undef glLinkProgram
+#undef glReleaseShaderCompiler
+#undef glRenderbufferStorage
+#undef glSampleCoverage
+#undef glShaderBinary
+#undef glShaderSource
+#undef glStencilFuncSeparate
+#undef glStencilMaskSeparate
+#undef glStencilOpSeparate
+#undef glUniform1f
+#undef glUniform1fv
+#undef glUniform1i
+#undef glUniform1iv
+#undef glUniform2f
+#undef glUniform2fv
+#undef glUniform2i
+#undef glUniform2iv
+#undef glUniform3f
+#undef glUniform3fv
+#undef glUniform3i
+#undef glUniform3iv
+#undef glUniform4f
+#undef glUniform4fv
+#undef glUniform4i
+#undef glUniform4iv
+#undef glUniformMatrix2fv
+#undef glUniformMatrix3fv
+#undef glUniformMatrix4fv
+#undef glUseProgram
+#undef glValidateProgram
+#undef glVertexAttrib1f
+#undef glVertexAttrib1fv
+#undef glVertexAttrib2f
+#undef glVertexAttrib2fv
+#undef glVertexAttrib3f
+#undef glVertexAttrib3fv
+#undef glVertexAttrib4f
+#undef glVertexAttrib4fv
+#undef glVertexAttribPointer
+
+class Q_OPENGL_EXPORT QGLFunctions
+{
+public:
+ QGLFunctions();
+ explicit QGLFunctions(const QGLContext *context);
+ ~QGLFunctions() {}
+
+ enum OpenGLFeature
+ {
+ Multitexture = 0x0001,
+ Shaders = 0x0002,
+ Buffers = 0x0004,
+ Framebuffers = 0x0008,
+ BlendColor = 0x0010,
+ BlendEquation = 0x0020,
+ BlendEquationSeparate = 0x0040,
+ BlendFuncSeparate = 0x0080,
+ BlendSubtract = 0x0100,
+ CompressedTextures = 0x0200,
+ Multisample = 0x0400,
+ StencilSeparate = 0x0800,
+ NPOTTextures = 0x1000
+ };
+ Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature)
+
+ QGLFunctions::OpenGLFeatures openGLFeatures() const;
+ bool hasOpenGLFeature(QGLFunctions::OpenGLFeature feature) const;
+
+ void initializeGLFunctions(const QGLContext *context = 0);
+
+ void glActiveTexture(GLenum texture);
+ void glAttachShader(GLuint program, GLuint shader);
+ void glBindAttribLocation(GLuint program, GLuint index, const char* name);
+ void glBindBuffer(GLenum target, GLuint buffer);
+ void glBindFramebuffer(GLenum target, GLuint framebuffer);
+ void glBindRenderbuffer(GLenum target, GLuint renderbuffer);
+ void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void glBlendEquation(GLenum mode);
+ void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage);
+ void glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data);
+ GLenum glCheckFramebufferStatus(GLenum target);
+ void glClearDepthf(GLclampf depth);
+ void glCompileShader(GLuint shader);
+ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+ void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+ GLuint glCreateProgram();
+ GLuint glCreateShader(GLenum type);
+ void glDeleteBuffers(GLsizei n, const GLuint* buffers);
+ void glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
+ void glDeleteProgram(GLuint program);
+ void glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
+ void glDeleteShader(GLuint shader);
+ void glDepthRangef(GLclampf zNear, GLclampf zFar);
+ void glDetachShader(GLuint program, GLuint shader);
+ void glDisableVertexAttribArray(GLuint index);
+ void glEnableVertexAttribArray(GLuint index);
+ void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ void glGenBuffers(GLsizei n, GLuint* buffers);
+ void glGenerateMipmap(GLenum target);
+ void glGenFramebuffers(GLsizei n, GLuint* framebuffers);
+ void glGenRenderbuffers(GLsizei n, GLuint* renderbuffers);
+ void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ int glGetAttribLocation(GLuint program, const char* name);
+ void glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+ void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void glGetProgramiv(GLuint program, GLenum pname, GLint* params);
+ void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+ void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+ void glGetShaderiv(GLuint shader, GLenum pname, GLint* params);
+ void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+ void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+ void glGetUniformfv(GLuint program, GLint location, GLfloat* params);
+ void glGetUniformiv(GLuint program, GLint location, GLint* params);
+ int glGetUniformLocation(GLuint program, const char* name);
+ void glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+ void glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+ void glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer);
+ GLboolean glIsBuffer(GLuint buffer);
+ GLboolean glIsFramebuffer(GLuint framebuffer);
+ GLboolean glIsProgram(GLuint program);
+ GLboolean glIsRenderbuffer(GLuint renderbuffer);
+ GLboolean glIsShader(GLuint shader);
+ void glLinkProgram(GLuint program);
+ void glReleaseShaderCompiler();
+ void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void glSampleCoverage(GLclampf value, GLboolean invert);
+ void glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
+ void glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length);
+ void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void glStencilMaskSeparate(GLenum face, GLuint mask);
+ void glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void glUniform1f(GLint location, GLfloat x);
+ void glUniform1fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform1i(GLint location, GLint x);
+ void glUniform1iv(GLint location, GLsizei count, const GLint* v);
+ void glUniform2f(GLint location, GLfloat x, GLfloat y);
+ void glUniform2fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform2i(GLint location, GLint x, GLint y);
+ void glUniform2iv(GLint location, GLsizei count, const GLint* v);
+ void glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void glUniform3fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform3i(GLint location, GLint x, GLint y, GLint z);
+ void glUniform3iv(GLint location, GLsizei count, const GLint* v);
+ void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void glUniform4fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void glUniform4iv(GLint location, GLsizei count, const GLint* v);
+ void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void glUseProgram(GLuint program);
+ void glValidateProgram(GLuint program);
+ void glVertexAttrib1f(GLuint indx, GLfloat x);
+ void glVertexAttrib1fv(GLuint indx, const GLfloat* values);
+ void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+ void glVertexAttrib2fv(GLuint indx, const GLfloat* values);
+ void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void glVertexAttrib3fv(GLuint indx, const GLfloat* values);
+ void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void glVertexAttrib4fv(GLuint indx, const GLfloat* values);
+ void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+
+private:
+ QGLFunctionsPrivate *d_ptr;
+ static bool isInitialized(const QGLFunctionsPrivate *d) { return d != 0; }
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGLFunctions::OpenGLFeatures)
+
+struct QGLFunctionsPrivate
+{
+ QGLFunctionsPrivate(const QGLContext *context = 0);
+
+#ifndef QT_OPENGL_ES_2
+ void (QGLF_APIENTRYP activeTexture)(GLenum texture);
+ void (QGLF_APIENTRYP attachShader)(GLuint program, GLuint shader);
+ void (QGLF_APIENTRYP bindAttribLocation)(GLuint program, GLuint index, const char* name);
+ void (QGLF_APIENTRYP bindBuffer)(GLenum target, GLuint buffer);
+ void (QGLF_APIENTRYP bindFramebuffer)(GLenum target, GLuint framebuffer);
+ void (QGLF_APIENTRYP bindRenderbuffer)(GLenum target, GLuint renderbuffer);
+ void (QGLF_APIENTRYP blendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (QGLF_APIENTRYP blendEquation)(GLenum mode);
+ void (QGLF_APIENTRYP blendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
+ void (QGLF_APIENTRYP blendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void (QGLF_APIENTRYP bufferData)(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage);
+ void (QGLF_APIENTRYP bufferSubData)(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data);
+ GLenum (QGLF_APIENTRYP checkFramebufferStatus)(GLenum target);
+ void (QGLF_APIENTRYP compileShader)(GLuint shader);
+ void (QGLF_APIENTRYP compressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+ void (QGLF_APIENTRYP compressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+ GLuint (QGLF_APIENTRYP createProgram)();
+ GLuint (QGLF_APIENTRYP createShader)(GLenum type);
+ void (QGLF_APIENTRYP deleteBuffers)(GLsizei n, const GLuint* buffers);
+ void (QGLF_APIENTRYP deleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
+ void (QGLF_APIENTRYP deleteProgram)(GLuint program);
+ void (QGLF_APIENTRYP deleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
+ void (QGLF_APIENTRYP deleteShader)(GLuint shader);
+ void (QGLF_APIENTRYP detachShader)(GLuint program, GLuint shader);
+ void (QGLF_APIENTRYP disableVertexAttribArray)(GLuint index);
+ void (QGLF_APIENTRYP enableVertexAttribArray)(GLuint index);
+ void (QGLF_APIENTRYP framebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ void (QGLF_APIENTRYP framebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ void (QGLF_APIENTRYP genBuffers)(GLsizei n, GLuint* buffers);
+ void (QGLF_APIENTRYP generateMipmap)(GLenum target);
+ void (QGLF_APIENTRYP genFramebuffers)(GLsizei n, GLuint* framebuffers);
+ void (QGLF_APIENTRYP genRenderbuffers)(GLsizei n, GLuint* renderbuffers);
+ void (QGLF_APIENTRYP getActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void (QGLF_APIENTRYP getActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void (QGLF_APIENTRYP getAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ int (QGLF_APIENTRYP getAttribLocation)(GLuint program, const char* name);
+ void (QGLF_APIENTRYP getBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (QGLF_APIENTRYP getFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void (QGLF_APIENTRYP getProgramiv)(GLuint program, GLenum pname, GLint* params);
+ void (QGLF_APIENTRYP getProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (QGLF_APIENTRYP getRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (QGLF_APIENTRYP getShaderiv)(GLuint shader, GLenum pname, GLint* params);
+ void (QGLF_APIENTRYP getShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (QGLF_APIENTRYP getShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void (QGLF_APIENTRYP getShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+ void (QGLF_APIENTRYP getUniformfv)(GLuint program, GLint location, GLfloat* params);
+ void (QGLF_APIENTRYP getUniformiv)(GLuint program, GLint location, GLint* params);
+ int (QGLF_APIENTRYP getUniformLocation)(GLuint program, const char* name);
+ void (QGLF_APIENTRYP getVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
+ void (QGLF_APIENTRYP getVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
+ void (QGLF_APIENTRYP getVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer);
+ GLboolean (QGLF_APIENTRYP isBuffer)(GLuint buffer);
+ GLboolean (QGLF_APIENTRYP isFramebuffer)(GLuint framebuffer);
+ GLboolean (QGLF_APIENTRYP isProgram)(GLuint program);
+ GLboolean (QGLF_APIENTRYP isRenderbuffer)(GLuint renderbuffer);
+ GLboolean (QGLF_APIENTRYP isShader)(GLuint shader);
+ void (QGLF_APIENTRYP linkProgram)(GLuint program);
+ void (QGLF_APIENTRYP releaseShaderCompiler)();
+ void (QGLF_APIENTRYP renderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void (QGLF_APIENTRYP sampleCoverage)(GLclampf value, GLboolean invert);
+ void (QGLF_APIENTRYP shaderBinary)(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
+ void (QGLF_APIENTRYP shaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length);
+ void (QGLF_APIENTRYP stencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void (QGLF_APIENTRYP stencilMaskSeparate)(GLenum face, GLuint mask);
+ void (QGLF_APIENTRYP stencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void (QGLF_APIENTRYP uniform1f)(GLint location, GLfloat x);
+ void (QGLF_APIENTRYP uniform1fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QGLF_APIENTRYP uniform1i)(GLint location, GLint x);
+ void (QGLF_APIENTRYP uniform1iv)(GLint location, GLsizei count, const GLint* v);
+ void (QGLF_APIENTRYP uniform2f)(GLint location, GLfloat x, GLfloat y);
+ void (QGLF_APIENTRYP uniform2fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QGLF_APIENTRYP uniform2i)(GLint location, GLint x, GLint y);
+ void (QGLF_APIENTRYP uniform2iv)(GLint location, GLsizei count, const GLint* v);
+ void (QGLF_APIENTRYP uniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void (QGLF_APIENTRYP uniform3fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QGLF_APIENTRYP uniform3i)(GLint location, GLint x, GLint y, GLint z);
+ void (QGLF_APIENTRYP uniform3iv)(GLint location, GLsizei count, const GLint* v);
+ void (QGLF_APIENTRYP uniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (QGLF_APIENTRYP uniform4fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QGLF_APIENTRYP uniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void (QGLF_APIENTRYP uniform4iv)(GLint location, GLsizei count, const GLint* v);
+ void (QGLF_APIENTRYP uniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (QGLF_APIENTRYP uniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (QGLF_APIENTRYP uniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (QGLF_APIENTRYP useProgram)(GLuint program);
+ void (QGLF_APIENTRYP validateProgram)(GLuint program);
+ void (QGLF_APIENTRYP vertexAttrib1f)(GLuint indx, GLfloat x);
+ void (QGLF_APIENTRYP vertexAttrib1fv)(GLuint indx, const GLfloat* values);
+ void (QGLF_APIENTRYP vertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
+ void (QGLF_APIENTRYP vertexAttrib2fv)(GLuint indx, const GLfloat* values);
+ void (QGLF_APIENTRYP vertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void (QGLF_APIENTRYP vertexAttrib3fv)(GLuint indx, const GLfloat* values);
+ void (QGLF_APIENTRYP vertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (QGLF_APIENTRYP vertexAttrib4fv)(GLuint indx, const GLfloat* values);
+ void (QGLF_APIENTRYP vertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+#endif
+};
+
+inline void QGLFunctions::glActiveTexture(GLenum texture)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glActiveTexture(texture);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->activeTexture(texture);
+#endif
+}
+
+inline void QGLFunctions::glAttachShader(GLuint program, GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glAttachShader(program, shader);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->attachShader(program, shader);
+#endif
+}
+
+inline void QGLFunctions::glBindAttribLocation(GLuint program, GLuint index, const char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBindAttribLocation(program, index, name);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->bindAttribLocation(program, index, name);
+#endif
+}
+
+inline void QGLFunctions::glBindBuffer(GLenum target, GLuint buffer)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glBindBuffer(target, buffer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->bindBuffer(target, buffer);
+#endif
+}
+
+inline void QGLFunctions::glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBindFramebuffer(target, framebuffer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->bindFramebuffer(target, framebuffer);
+#endif
+}
+
+inline void QGLFunctions::glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBindRenderbuffer(target, renderbuffer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->bindRenderbuffer(target, renderbuffer);
+#endif
+}
+
+inline void QGLFunctions::glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendColor(red, green, blue, alpha);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->blendColor(red, green, blue, alpha);
+#endif
+}
+
+inline void QGLFunctions::glBlendEquation(GLenum mode)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendEquation(mode);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->blendEquation(mode);
+#endif
+}
+
+inline void QGLFunctions::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendEquationSeparate(modeRGB, modeAlpha);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->blendEquationSeparate(modeRGB, modeAlpha);
+#endif
+}
+
+inline void QGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+#endif
+}
+
+inline void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glBufferData(target, size, data, usage);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->bufferData(target, size, data, usage);
+#endif
+}
+
+inline void QGLFunctions::glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glBufferSubData(target, offset, size, data);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->bufferSubData(target, offset, size, data);
+#endif
+}
+
+inline GLenum QGLFunctions::glCheckFramebufferStatus(GLenum target)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glCheckFramebufferStatus(target);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->checkFramebufferStatus(target);
+#endif
+}
+
+inline void QGLFunctions::glClearDepthf(GLclampf depth)
+{
+#ifndef QT_OPENGL_ES
+ ::glClearDepth(depth);
+#else
+ ::glClearDepthf(depth);
+#endif
+}
+
+inline void QGLFunctions::glCompileShader(GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glCompileShader(shader);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->compileShader(shader);
+#endif
+}
+
+inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+#endif
+}
+
+inline void QGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+#endif
+}
+
+inline GLuint QGLFunctions::glCreateProgram()
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glCreateProgram();
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->createProgram();
+#endif
+}
+
+inline GLuint QGLFunctions::glCreateShader(GLenum type)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glCreateShader(type);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->createShader(type);
+#endif
+}
+
+inline void QGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glDeleteBuffers(n, buffers);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->deleteBuffers(n, buffers);
+#endif
+}
+
+inline void QGLFunctions::glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteFramebuffers(n, framebuffers);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->deleteFramebuffers(n, framebuffers);
+#endif
+}
+
+inline void QGLFunctions::glDeleteProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteProgram(program);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->deleteProgram(program);
+#endif
+}
+
+inline void QGLFunctions::glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteRenderbuffers(n, renderbuffers);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->deleteRenderbuffers(n, renderbuffers);
+#endif
+}
+
+inline void QGLFunctions::glDeleteShader(GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteShader(shader);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->deleteShader(shader);
+#endif
+}
+
+inline void QGLFunctions::glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+#ifndef QT_OPENGL_ES
+ ::glDepthRange(zNear, zFar);
+#else
+ ::glDepthRangef(zNear, zFar);
+#endif
+}
+
+inline void QGLFunctions::glDetachShader(GLuint program, GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDetachShader(program, shader);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->detachShader(program, shader);
+#endif
+}
+
+inline void QGLFunctions::glDisableVertexAttribArray(GLuint index)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDisableVertexAttribArray(index);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->disableVertexAttribArray(index);
+#endif
+}
+
+inline void QGLFunctions::glEnableVertexAttribArray(GLuint index)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glEnableVertexAttribArray(index);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->enableVertexAttribArray(index);
+#endif
+}
+
+inline void QGLFunctions::glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+#endif
+}
+
+inline void QGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glFramebufferTexture2D(target, attachment, textarget, texture, level);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->framebufferTexture2D(target, attachment, textarget, texture, level);
+#endif
+}
+
+inline void QGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glGenBuffers(n, buffers);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->genBuffers(n, buffers);
+#endif
+}
+
+inline void QGLFunctions::glGenerateMipmap(GLenum target)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGenerateMipmap(target);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->generateMipmap(target);
+#endif
+}
+
+inline void QGLFunctions::glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGenFramebuffers(n, framebuffers);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->genFramebuffers(n, framebuffers);
+#endif
+}
+
+inline void QGLFunctions::glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGenRenderbuffers(n, renderbuffers);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->genRenderbuffers(n, renderbuffers);
+#endif
+}
+
+inline void QGLFunctions::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetActiveAttrib(program, index, bufsize, length, size, type, name);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getActiveAttrib(program, index, bufsize, length, size, type, name);
+#endif
+}
+
+inline void QGLFunctions::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetActiveUniform(program, index, bufsize, length, size, type, name);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getActiveUniform(program, index, bufsize, length, size, type, name);
+#endif
+}
+
+inline void QGLFunctions::glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetAttachedShaders(program, maxcount, count, shaders);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getAttachedShaders(program, maxcount, count, shaders);
+#endif
+}
+
+inline int QGLFunctions::glGetAttribLocation(GLuint program, const char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glGetAttribLocation(program, name);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->getAttribLocation(program, name);
+#endif
+}
+
+inline void QGLFunctions::glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetBufferParameteriv(target, pname, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getBufferParameteriv(target, pname, params);
+#endif
+}
+
+inline void QGLFunctions::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
+#endif
+}
+
+inline void QGLFunctions::glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetProgramiv(program, pname, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getProgramiv(program, pname, params);
+#endif
+}
+
+inline void QGLFunctions::glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetProgramInfoLog(program, bufsize, length, infolog);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getProgramInfoLog(program, bufsize, length, infolog);
+#endif
+}
+
+inline void QGLFunctions::glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetRenderbufferParameteriv(target, pname, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getRenderbufferParameteriv(target, pname, params);
+#endif
+}
+
+inline void QGLFunctions::glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderiv(shader, pname, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getShaderiv(shader, pname, params);
+#endif
+}
+
+inline void QGLFunctions::glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderInfoLog(shader, bufsize, length, infolog);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getShaderInfoLog(shader, bufsize, length, infolog);
+#endif
+}
+
+inline void QGLFunctions::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+#endif
+}
+
+inline void QGLFunctions::glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderSource(shader, bufsize, length, source);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getShaderSource(shader, bufsize, length, source);
+#endif
+}
+
+inline void QGLFunctions::glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetUniformfv(program, location, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getUniformfv(program, location, params);
+#endif
+}
+
+inline void QGLFunctions::glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetUniformiv(program, location, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getUniformiv(program, location, params);
+#endif
+}
+
+inline int QGLFunctions::glGetUniformLocation(GLuint program, const char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glGetUniformLocation(program, name);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->getUniformLocation(program, name);
+#endif
+}
+
+inline void QGLFunctions::glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetVertexAttribfv(index, pname, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getVertexAttribfv(index, pname, params);
+#endif
+}
+
+inline void QGLFunctions::glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetVertexAttribiv(index, pname, params);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getVertexAttribiv(index, pname, params);
+#endif
+}
+
+inline void QGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetVertexAttribPointerv(index, pname, pointer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->getVertexAttribPointerv(index, pname, pointer);
+#endif
+}
+
+inline GLboolean QGLFunctions::glIsBuffer(GLuint buffer)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ return ::glIsBuffer(buffer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->isBuffer(buffer);
+#endif
+}
+
+inline GLboolean QGLFunctions::glIsFramebuffer(GLuint framebuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glIsFramebuffer(framebuffer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->isFramebuffer(framebuffer);
+#endif
+}
+
+inline GLboolean QGLFunctions::glIsProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glIsProgram(program);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->isProgram(program);
+#endif
+}
+
+inline GLboolean QGLFunctions::glIsRenderbuffer(GLuint renderbuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glIsRenderbuffer(renderbuffer);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->isRenderbuffer(renderbuffer);
+#endif
+}
+
+inline GLboolean QGLFunctions::glIsShader(GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ return ::glIsShader(shader);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ return d_ptr->isShader(shader);
+#endif
+}
+
+inline void QGLFunctions::glLinkProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glLinkProgram(program);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->linkProgram(program);
+#endif
+}
+
+inline void QGLFunctions::glReleaseShaderCompiler()
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glReleaseShaderCompiler();
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->releaseShaderCompiler();
+#endif
+}
+
+inline void QGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glRenderbufferStorage(target, internalformat, width, height);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->renderbufferStorage(target, internalformat, width, height);
+#endif
+}
+
+inline void QGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert)
+{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+ ::glSampleCoverage(value, invert);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->sampleCoverage(value, invert);
+#endif
+}
+
+inline void QGLFunctions::glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glShaderBinary(n, shaders, binaryformat, binary, length);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->shaderBinary(n, shaders, binaryformat, binary, length);
+#endif
+}
+
+inline void QGLFunctions::glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glShaderSource(shader, count, string, length);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->shaderSource(shader, count, string, length);
+#endif
+}
+
+inline void QGLFunctions::glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glStencilFuncSeparate(face, func, ref, mask);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->stencilFuncSeparate(face, func, ref, mask);
+#endif
+}
+
+inline void QGLFunctions::glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glStencilMaskSeparate(face, mask);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->stencilMaskSeparate(face, mask);
+#endif
+}
+
+inline void QGLFunctions::glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glStencilOpSeparate(face, fail, zfail, zpass);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->stencilOpSeparate(face, fail, zfail, zpass);
+#endif
+}
+
+inline void QGLFunctions::glUniform1f(GLint location, GLfloat x)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1f(location, x);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform1f(location, x);
+#endif
+}
+
+inline void QGLFunctions::glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1fv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform1fv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniform1i(GLint location, GLint x)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1i(location, x);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform1i(location, x);
+#endif
+}
+
+inline void QGLFunctions::glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1iv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform1iv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2f(location, x, y);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform2f(location, x, y);
+#endif
+}
+
+inline void QGLFunctions::glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2fv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform2fv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniform2i(GLint location, GLint x, GLint y)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2i(location, x, y);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform2i(location, x, y);
+#endif
+}
+
+inline void QGLFunctions::glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2iv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform2iv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3f(location, x, y, z);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform3f(location, x, y, z);
+#endif
+}
+
+inline void QGLFunctions::glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3fv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform3fv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3i(location, x, y, z);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform3i(location, x, y, z);
+#endif
+}
+
+inline void QGLFunctions::glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3iv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform3iv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4f(location, x, y, z, w);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform4f(location, x, y, z, w);
+#endif
+}
+
+inline void QGLFunctions::glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4fv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform4fv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4i(location, x, y, z, w);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform4i(location, x, y, z, w);
+#endif
+}
+
+inline void QGLFunctions::glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4iv(location, count, v);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniform4iv(location, count, v);
+#endif
+}
+
+inline void QGLFunctions::glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniformMatrix2fv(location, count, transpose, value);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniformMatrix2fv(location, count, transpose, value);
+#endif
+}
+
+inline void QGLFunctions::glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniformMatrix3fv(location, count, transpose, value);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniformMatrix3fv(location, count, transpose, value);
+#endif
+}
+
+inline void QGLFunctions::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniformMatrix4fv(location, count, transpose, value);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->uniformMatrix4fv(location, count, transpose, value);
+#endif
+}
+
+inline void QGLFunctions::glUseProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUseProgram(program);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->useProgram(program);
+#endif
+}
+
+inline void QGLFunctions::glValidateProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glValidateProgram(program);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->validateProgram(program);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib1f(indx, x);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib1f(indx, x);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib1fv(indx, values);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib1fv(indx, values);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib2f(indx, x, y);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib2f(indx, x, y);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib2fv(indx, values);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib2fv(indx, values);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib3f(indx, x, y, z);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib3f(indx, x, y, z);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib3fv(indx, values);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib3fv(indx, values);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib4f(indx, x, y, z, w);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib4f(indx, x, y, z, w);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib4fv(indx, values);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttrib4fv(indx, values);
+#endif
+}
+
+inline void QGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
+#else
+ Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
+ d_ptr->vertexAttribPointer(indx, size, type, normalized, stride, ptr);
+#endif
+}
+
+#ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#endif
+#ifndef GL_ACTIVE_ATTRIBUTES
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#endif
+#ifndef GL_ACTIVE_TEXTURE
+#define GL_ACTIVE_TEXTURE 0x84E0
+#endif
+#ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#endif
+#ifndef GL_ACTIVE_UNIFORMS
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#endif
+#ifndef GL_ALIASED_LINE_WIDTH_RANGE
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#endif
+#ifndef GL_ALIASED_POINT_SIZE_RANGE
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#endif
+#ifndef GL_ALPHA
+#define GL_ALPHA 0x1906
+#endif
+#ifndef GL_ALPHA_BITS
+#define GL_ALPHA_BITS 0x0D55
+#endif
+#ifndef GL_ALWAYS
+#define GL_ALWAYS 0x0207
+#endif
+#ifndef GL_ARRAY_BUFFER
+#define GL_ARRAY_BUFFER 0x8892
+#endif
+#ifndef GL_ARRAY_BUFFER_BINDING
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#endif
+#ifndef GL_ATTACHED_SHADERS
+#define GL_ATTACHED_SHADERS 0x8B85
+#endif
+#ifndef GL_BACK
+#define GL_BACK 0x0405
+#endif
+#ifndef GL_BLEND
+#define GL_BLEND 0x0BE2
+#endif
+#ifndef GL_BLEND_COLOR
+#define GL_BLEND_COLOR 0x8005
+#endif
+#ifndef GL_BLEND_DST_ALPHA
+#define GL_BLEND_DST_ALPHA 0x80CA
+#endif
+#ifndef GL_BLEND_DST_RGB
+#define GL_BLEND_DST_RGB 0x80C8
+#endif
+#ifndef GL_BLEND_EQUATION
+#define GL_BLEND_EQUATION 0x8009
+#endif
+#ifndef GL_BLEND_EQUATION_ALPHA
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#endif
+#ifndef GL_BLEND_EQUATION_RGB
+#define GL_BLEND_EQUATION_RGB 0x8009
+#endif
+#ifndef GL_BLEND_SRC_ALPHA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#endif
+#ifndef GL_BLEND_SRC_RGB
+#define GL_BLEND_SRC_RGB 0x80C9
+#endif
+#ifndef GL_BLUE_BITS
+#define GL_BLUE_BITS 0x0D54
+#endif
+#ifndef GL_BOOL
+#define GL_BOOL 0x8B56
+#endif
+#ifndef GL_BOOL_VEC2
+#define GL_BOOL_VEC2 0x8B57
+#endif
+#ifndef GL_BOOL_VEC3
+#define GL_BOOL_VEC3 0x8B58
+#endif
+#ifndef GL_BOOL_VEC4
+#define GL_BOOL_VEC4 0x8B59
+#endif
+#ifndef GL_BUFFER_SIZE
+#define GL_BUFFER_SIZE 0x8764
+#endif
+#ifndef GL_BUFFER_USAGE
+#define GL_BUFFER_USAGE 0x8765
+#endif
+#ifndef GL_BYTE
+#define GL_BYTE 0x1400
+#endif
+#ifndef GL_CCW
+#define GL_CCW 0x0901
+#endif
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif
+#ifndef GL_COLOR_ATTACHMENT0
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#endif
+#ifndef GL_COLOR_BUFFER_BIT
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#endif
+#ifndef GL_COLOR_CLEAR_VALUE
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#endif
+#ifndef GL_COLOR_WRITEMASK
+#define GL_COLOR_WRITEMASK 0x0C23
+#endif
+#ifndef GL_COMPILE_STATUS
+#define GL_COMPILE_STATUS 0x8B81
+#endif
+#ifndef GL_COMPRESSED_TEXTURE_FORMATS
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#endif
+#ifndef GL_CONSTANT_ALPHA
+#define GL_CONSTANT_ALPHA 0x8003
+#endif
+#ifndef GL_CONSTANT_COLOR
+#define GL_CONSTANT_COLOR 0x8001
+#endif
+#ifndef GL_CULL_FACE
+#define GL_CULL_FACE 0x0B44
+#endif
+#ifndef GL_CULL_FACE_MODE
+#define GL_CULL_FACE_MODE 0x0B45
+#endif
+#ifndef GL_CURRENT_PROGRAM
+#define GL_CURRENT_PROGRAM 0x8B8D
+#endif
+#ifndef GL_CURRENT_VERTEX_ATTRIB
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#endif
+#ifndef GL_CW
+#define GL_CW 0x0900
+#endif
+#ifndef GL_DECR
+#define GL_DECR 0x1E03
+#endif
+#ifndef GL_DECR_WRAP
+#define GL_DECR_WRAP 0x8508
+#endif
+#ifndef GL_DELETE_STATUS
+#define GL_DELETE_STATUS 0x8B80
+#endif
+#ifndef GL_DEPTH_ATTACHMENT
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#endif
+#ifndef GL_DEPTH_BITS
+#define GL_DEPTH_BITS 0x0D56
+#endif
+#ifndef GL_DEPTH_BUFFER_BIT
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#endif
+#ifndef GL_DEPTH_CLEAR_VALUE
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#endif
+#ifndef GL_DEPTH_COMPONENT
+#define GL_DEPTH_COMPONENT 0x1902
+#endif
+#ifndef GL_DEPTH_COMPONENT16
+#define GL_DEPTH_COMPONENT16 0x81A5
+#endif
+#ifndef GL_DEPTH_FUNC
+#define GL_DEPTH_FUNC 0x0B74
+#endif
+#ifndef GL_DEPTH_RANGE
+#define GL_DEPTH_RANGE 0x0B70
+#endif
+#ifndef GL_DEPTH_TEST
+#define GL_DEPTH_TEST 0x0B71
+#endif
+#ifndef GL_DEPTH_WRITEMASK
+#define GL_DEPTH_WRITEMASK 0x0B72
+#endif
+#ifndef GL_DITHER
+#define GL_DITHER 0x0BD0
+#endif
+#ifndef GL_DONT_CARE
+#define GL_DONT_CARE 0x1100
+#endif
+#ifndef GL_DST_ALPHA
+#define GL_DST_ALPHA 0x0304
+#endif
+#ifndef GL_DST_COLOR
+#define GL_DST_COLOR 0x0306
+#endif
+#ifndef GL_DYNAMIC_DRAW
+#define GL_DYNAMIC_DRAW 0x88E8
+#endif
+#ifndef GL_ELEMENT_ARRAY_BUFFER
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#endif
+#ifndef GL_ELEMENT_ARRAY_BUFFER_BINDING
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#endif
+#ifndef GL_EQUAL
+#define GL_EQUAL 0x0202
+#endif
+#ifndef GL_EXTENSIONS
+#define GL_EXTENSIONS 0x1F03
+#endif
+#ifndef GL_FALSE
+#define GL_FALSE 0
+#endif
+#ifndef GL_FASTEST
+#define GL_FASTEST 0x1101
+#endif
+#ifndef GL_FIXED
+#define GL_FIXED 0x140C
+#endif
+#ifndef GL_FLOAT
+#define GL_FLOAT 0x1406
+#endif
+#ifndef GL_FLOAT_MAT2
+#define GL_FLOAT_MAT2 0x8B5A
+#endif
+#ifndef GL_FLOAT_MAT3
+#define GL_FLOAT_MAT3 0x8B5B
+#endif
+#ifndef GL_FLOAT_MAT4
+#define GL_FLOAT_MAT4 0x8B5C
+#endif
+#ifndef GL_FLOAT_VEC2
+#define GL_FLOAT_VEC2 0x8B50
+#endif
+#ifndef GL_FLOAT_VEC3
+#define GL_FLOAT_VEC3 0x8B51
+#endif
+#ifndef GL_FLOAT_VEC4
+#define GL_FLOAT_VEC4 0x8B52
+#endif
+#ifndef GL_FRAGMENT_SHADER
+#define GL_FRAGMENT_SHADER 0x8B30
+#endif
+#ifndef GL_FRAMEBUFFER
+#define GL_FRAMEBUFFER 0x8D40
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#endif
+#ifndef GL_FRAMEBUFFER_BINDING
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#endif
+#ifndef GL_FRAMEBUFFER_COMPLETE
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#endif
+#ifndef GL_FRAMEBUFFER_UNSUPPORTED
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#endif
+#ifndef GL_FRONT
+#define GL_FRONT 0x0404
+#endif
+#ifndef GL_FRONT_AND_BACK
+#define GL_FRONT_AND_BACK 0x0408
+#endif
+#ifndef GL_FRONT_FACE
+#define GL_FRONT_FACE 0x0B46
+#endif
+#ifndef GL_FUNC_ADD
+#define GL_FUNC_ADD 0x8006
+#endif
+#ifndef GL_FUNC_REVERSE_SUBTRACT
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#endif
+#ifndef GL_FUNC_SUBTRACT
+#define GL_FUNC_SUBTRACT 0x800A
+#endif
+#ifndef GL_GENERATE_MIPMAP_HINT
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#endif
+#ifndef GL_GEQUAL
+#define GL_GEQUAL 0x0206
+#endif
+#ifndef GL_GREATER
+#define GL_GREATER 0x0204
+#endif
+#ifndef GL_GREEN_BITS
+#define GL_GREEN_BITS 0x0D53
+#endif
+#ifndef GL_HIGH_FLOAT
+#define GL_HIGH_FLOAT 0x8DF2
+#endif
+#ifndef GL_HIGH_INT
+#define GL_HIGH_INT 0x8DF5
+#endif
+#ifndef GL_IMPLEMENTATION_COLOR_READ_FORMAT
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#endif
+#ifndef GL_IMPLEMENTATION_COLOR_READ_TYPE
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#endif
+#ifndef GL_INCR
+#define GL_INCR 0x1E02
+#endif
+#ifndef GL_INCR_WRAP
+#define GL_INCR_WRAP 0x8507
+#endif
+#ifndef GL_INFO_LOG_LENGTH
+#define GL_INFO_LOG_LENGTH 0x8B84
+#endif
+#ifndef GL_INT
+#define GL_INT 0x1404
+#endif
+#ifndef GL_INT_VEC2
+#define GL_INT_VEC2 0x8B53
+#endif
+#ifndef GL_INT_VEC3
+#define GL_INT_VEC3 0x8B54
+#endif
+#ifndef GL_INT_VEC4
+#define GL_INT_VEC4 0x8B55
+#endif
+#ifndef GL_INVALID_ENUM
+#define GL_INVALID_ENUM 0x0500
+#endif
+#ifndef GL_INVALID_FRAMEBUFFER_OPERATION
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#endif
+#ifndef GL_INVALID_OPERATION
+#define GL_INVALID_OPERATION 0x0502
+#endif
+#ifndef GL_INVALID_VALUE
+#define GL_INVALID_VALUE 0x0501
+#endif
+#ifndef GL_INVERT
+#define GL_INVERT 0x150A
+#endif
+#ifndef GL_KEEP
+#define GL_KEEP 0x1E00
+#endif
+#ifndef GL_LEQUAL
+#define GL_LEQUAL 0x0203
+#endif
+#ifndef GL_LESS
+#define GL_LESS 0x0201
+#endif
+#ifndef GL_LINEAR
+#define GL_LINEAR 0x2601
+#endif
+#ifndef GL_LINEAR_MIPMAP_LINEAR
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#endif
+#ifndef GL_LINEAR_MIPMAP_NEAREST
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#endif
+#ifndef GL_LINE_LOOP
+#define GL_LINE_LOOP 0x0002
+#endif
+#ifndef GL_LINES
+#define GL_LINES 0x0001
+#endif
+#ifndef GL_LINE_STRIP
+#define GL_LINE_STRIP 0x0003
+#endif
+#ifndef GL_LINE_WIDTH
+#define GL_LINE_WIDTH 0x0B21
+#endif
+#ifndef GL_LINK_STATUS
+#define GL_LINK_STATUS 0x8B82
+#endif
+#ifndef GL_LOW_FLOAT
+#define GL_LOW_FLOAT 0x8DF0
+#endif
+#ifndef GL_LOW_INT
+#define GL_LOW_INT 0x8DF3
+#endif
+#ifndef GL_LUMINANCE
+#define GL_LUMINANCE 0x1909
+#endif
+#ifndef GL_LUMINANCE_ALPHA
+#define GL_LUMINANCE_ALPHA 0x190A
+#endif
+#ifndef GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#endif
+#ifndef GL_MAX_CUBE_MAP_TEXTURE_SIZE
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#endif
+#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#endif
+#ifndef GL_MAX_RENDERBUFFER_SIZE
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#endif
+#ifndef GL_MAX_TEXTURE_IMAGE_UNITS
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#endif
+#ifndef GL_MAX_TEXTURE_SIZE
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#endif
+#ifndef GL_MAX_VARYING_VECTORS
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#endif
+#ifndef GL_MAX_VERTEX_ATTRIBS
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#endif
+#ifndef GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#endif
+#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#endif
+#ifndef GL_MAX_VIEWPORT_DIMS
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#endif
+#ifndef GL_MEDIUM_FLOAT
+#define GL_MEDIUM_FLOAT 0x8DF1
+#endif
+#ifndef GL_MEDIUM_INT
+#define GL_MEDIUM_INT 0x8DF4
+#endif
+#ifndef GL_MIRRORED_REPEAT
+#define GL_MIRRORED_REPEAT 0x8370
+#endif
+#ifndef GL_NEAREST
+#define GL_NEAREST 0x2600
+#endif
+#ifndef GL_NEAREST_MIPMAP_LINEAR
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#endif
+#ifndef GL_NEAREST_MIPMAP_NEAREST
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#endif
+#ifndef GL_NEVER
+#define GL_NEVER 0x0200
+#endif
+#ifndef GL_NICEST
+#define GL_NICEST 0x1102
+#endif
+#ifndef GL_NO_ERROR
+#define GL_NO_ERROR 0
+#endif
+#ifndef GL_NONE
+#define GL_NONE 0
+#endif
+#ifndef GL_NOTEQUAL
+#define GL_NOTEQUAL 0x0205
+#endif
+#ifndef GL_NUM_COMPRESSED_TEXTURE_FORMATS
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#endif
+#ifndef GL_NUM_SHADER_BINARY_FORMATS
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#endif
+#ifndef GL_ONE
+#define GL_ONE 1
+#endif
+#ifndef GL_ONE_MINUS_CONSTANT_ALPHA
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#endif
+#ifndef GL_ONE_MINUS_CONSTANT_COLOR
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#endif
+#ifndef GL_ONE_MINUS_DST_ALPHA
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#endif
+#ifndef GL_ONE_MINUS_DST_COLOR
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#endif
+#ifndef GL_ONE_MINUS_SRC_ALPHA
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#endif
+#ifndef GL_ONE_MINUS_SRC_COLOR
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#endif
+#ifndef GL_OUT_OF_MEMORY
+#define GL_OUT_OF_MEMORY 0x0505
+#endif
+#ifndef GL_PACK_ALIGNMENT
+#define GL_PACK_ALIGNMENT 0x0D05
+#endif
+#ifndef GL_POINTS
+#define GL_POINTS 0x0000
+#endif
+#ifndef GL_POLYGON_OFFSET_FACTOR
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#endif
+#ifndef GL_POLYGON_OFFSET_FILL
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#endif
+#ifndef GL_POLYGON_OFFSET_UNITS
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#endif
+#ifndef GL_RED_BITS
+#define GL_RED_BITS 0x0D52
+#endif
+#ifndef GL_RENDERBUFFER
+#define GL_RENDERBUFFER 0x8D41
+#endif
+#ifndef GL_RENDERBUFFER_ALPHA_SIZE
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#endif
+#ifndef GL_RENDERBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#endif
+#ifndef GL_RENDERBUFFER_BLUE_SIZE
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#endif
+#ifndef GL_RENDERBUFFER_DEPTH_SIZE
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#endif
+#ifndef GL_RENDERBUFFER_GREEN_SIZE
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#endif
+#ifndef GL_RENDERBUFFER_HEIGHT
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#endif
+#ifndef GL_RENDERBUFFER_INTERNAL_FORMAT
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#endif
+#ifndef GL_RENDERBUFFER_RED_SIZE
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#endif
+#ifndef GL_RENDERBUFFER_STENCIL_SIZE
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#endif
+#ifndef GL_RENDERBUFFER_WIDTH
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#endif
+#ifndef GL_RENDERER
+#define GL_RENDERER 0x1F01
+#endif
+#ifndef GL_REPEAT
+#define GL_REPEAT 0x2901
+#endif
+#ifndef GL_REPLACE
+#define GL_REPLACE 0x1E01
+#endif
+#ifndef GL_RGB
+#define GL_RGB 0x1907
+#endif
+#ifndef GL_RGB565
+#define GL_RGB565 0x8D62
+#endif
+#ifndef GL_RGB5_A1
+#define GL_RGB5_A1 0x8057
+#endif
+#ifndef GL_RGBA
+#define GL_RGBA 0x1908
+#endif
+#ifndef GL_RGBA4
+#define GL_RGBA4 0x8056
+#endif
+#ifndef GL_SAMPLE_ALPHA_TO_COVERAGE
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#endif
+#ifndef GL_SAMPLE_BUFFERS
+#define GL_SAMPLE_BUFFERS 0x80A8
+#endif
+#ifndef GL_SAMPLE_COVERAGE
+#define GL_SAMPLE_COVERAGE 0x80A0
+#endif
+#ifndef GL_SAMPLE_COVERAGE_INVERT
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#endif
+#ifndef GL_SAMPLE_COVERAGE_VALUE
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#endif
+#ifndef GL_SAMPLER_2D
+#define GL_SAMPLER_2D 0x8B5E
+#endif
+#ifndef GL_SAMPLER_CUBE
+#define GL_SAMPLER_CUBE 0x8B60
+#endif
+#ifndef GL_SAMPLES
+#define GL_SAMPLES 0x80A9
+#endif
+#ifndef GL_SCISSOR_BOX
+#define GL_SCISSOR_BOX 0x0C10
+#endif
+#ifndef GL_SCISSOR_TEST
+#define GL_SCISSOR_TEST 0x0C11
+#endif
+#ifndef GL_SHADER_BINARY_FORMATS
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#endif
+#ifndef GL_SHADER_COMPILER
+#define GL_SHADER_COMPILER 0x8DFA
+#endif
+#ifndef GL_SHADER_SOURCE_LENGTH
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#endif
+#ifndef GL_SHADER_TYPE
+#define GL_SHADER_TYPE 0x8B4F
+#endif
+#ifndef GL_SHADING_LANGUAGE_VERSION
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#endif
+#ifndef GL_SHORT
+#define GL_SHORT 0x1402
+#endif
+#ifndef GL_SRC_ALPHA
+#define GL_SRC_ALPHA 0x0302
+#endif
+#ifndef GL_SRC_ALPHA_SATURATE
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#endif
+#ifndef GL_SRC_COLOR
+#define GL_SRC_COLOR 0x0300
+#endif
+#ifndef GL_STATIC_DRAW
+#define GL_STATIC_DRAW 0x88E4
+#endif
+#ifndef GL_STENCIL_ATTACHMENT
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#endif
+#ifndef GL_STENCIL_BACK_FAIL
+#define GL_STENCIL_BACK_FAIL 0x8801
+#endif
+#ifndef GL_STENCIL_BACK_FUNC
+#define GL_STENCIL_BACK_FUNC 0x8800
+#endif
+#ifndef GL_STENCIL_BACK_PASS_DEPTH_FAIL
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#endif
+#ifndef GL_STENCIL_BACK_PASS_DEPTH_PASS
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#endif
+#ifndef GL_STENCIL_BACK_REF
+#define GL_STENCIL_BACK_REF 0x8CA3
+#endif
+#ifndef GL_STENCIL_BACK_VALUE_MASK
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#endif
+#ifndef GL_STENCIL_BACK_WRITEMASK
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#endif
+#ifndef GL_STENCIL_BITS
+#define GL_STENCIL_BITS 0x0D57
+#endif
+#ifndef GL_STENCIL_BUFFER_BIT
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#endif
+#ifndef GL_STENCIL_CLEAR_VALUE
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#endif
+#ifndef GL_STENCIL_FAIL
+#define GL_STENCIL_FAIL 0x0B94
+#endif
+#ifndef GL_STENCIL_FUNC
+#define GL_STENCIL_FUNC 0x0B92
+#endif
+#ifndef GL_STENCIL_INDEX
+#define GL_STENCIL_INDEX 0x1901
+#endif
+#ifndef GL_STENCIL_INDEX8
+#define GL_STENCIL_INDEX8 0x8D48
+#endif
+#ifndef GL_STENCIL_PASS_DEPTH_FAIL
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#endif
+#ifndef GL_STENCIL_PASS_DEPTH_PASS
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#endif
+#ifndef GL_STENCIL_REF
+#define GL_STENCIL_REF 0x0B97
+#endif
+#ifndef GL_STENCIL_TEST
+#define GL_STENCIL_TEST 0x0B90
+#endif
+#ifndef GL_STENCIL_VALUE_MASK
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#endif
+#ifndef GL_STENCIL_WRITEMASK
+#define GL_STENCIL_WRITEMASK 0x0B98
+#endif
+#ifndef GL_STREAM_DRAW
+#define GL_STREAM_DRAW 0x88E0
+#endif
+#ifndef GL_SUBPIXEL_BITS
+#define GL_SUBPIXEL_BITS 0x0D50
+#endif
+#ifndef GL_TEXTURE0
+#define GL_TEXTURE0 0x84C0
+#endif
+#ifndef GL_TEXTURE
+#define GL_TEXTURE 0x1702
+#endif
+#ifndef GL_TEXTURE10
+#define GL_TEXTURE10 0x84CA
+#endif
+#ifndef GL_TEXTURE1
+#define GL_TEXTURE1 0x84C1
+#endif
+#ifndef GL_TEXTURE11
+#define GL_TEXTURE11 0x84CB
+#endif
+#ifndef GL_TEXTURE12
+#define GL_TEXTURE12 0x84CC
+#endif
+#ifndef GL_TEXTURE13
+#define GL_TEXTURE13 0x84CD
+#endif
+#ifndef GL_TEXTURE14
+#define GL_TEXTURE14 0x84CE
+#endif
+#ifndef GL_TEXTURE15
+#define GL_TEXTURE15 0x84CF
+#endif
+#ifndef GL_TEXTURE16
+#define GL_TEXTURE16 0x84D0
+#endif
+#ifndef GL_TEXTURE17
+#define GL_TEXTURE17 0x84D1
+#endif
+#ifndef GL_TEXTURE18
+#define GL_TEXTURE18 0x84D2
+#endif
+#ifndef GL_TEXTURE19
+#define GL_TEXTURE19 0x84D3
+#endif
+#ifndef GL_TEXTURE20
+#define GL_TEXTURE20 0x84D4
+#endif
+#ifndef GL_TEXTURE2
+#define GL_TEXTURE2 0x84C2
+#endif
+#ifndef GL_TEXTURE21
+#define GL_TEXTURE21 0x84D5
+#endif
+#ifndef GL_TEXTURE22
+#define GL_TEXTURE22 0x84D6
+#endif
+#ifndef GL_TEXTURE23
+#define GL_TEXTURE23 0x84D7
+#endif
+#ifndef GL_TEXTURE24
+#define GL_TEXTURE24 0x84D8
+#endif
+#ifndef GL_TEXTURE25
+#define GL_TEXTURE25 0x84D9
+#endif
+#ifndef GL_TEXTURE26
+#define GL_TEXTURE26 0x84DA
+#endif
+#ifndef GL_TEXTURE27
+#define GL_TEXTURE27 0x84DB
+#endif
+#ifndef GL_TEXTURE28
+#define GL_TEXTURE28 0x84DC
+#endif
+#ifndef GL_TEXTURE29
+#define GL_TEXTURE29 0x84DD
+#endif
+#ifndef GL_TEXTURE_2D
+#define GL_TEXTURE_2D 0x0DE1
+#endif
+#ifndef GL_TEXTURE30
+#define GL_TEXTURE30 0x84DE
+#endif
+#ifndef GL_TEXTURE3
+#define GL_TEXTURE3 0x84C3
+#endif
+#ifndef GL_TEXTURE31
+#define GL_TEXTURE31 0x84DF
+#endif
+#ifndef GL_TEXTURE4
+#define GL_TEXTURE4 0x84C4
+#endif
+#ifndef GL_TEXTURE5
+#define GL_TEXTURE5 0x84C5
+#endif
+#ifndef GL_TEXTURE6
+#define GL_TEXTURE6 0x84C6
+#endif
+#ifndef GL_TEXTURE7
+#define GL_TEXTURE7 0x84C7
+#endif
+#ifndef GL_TEXTURE8
+#define GL_TEXTURE8 0x84C8
+#endif
+#ifndef GL_TEXTURE9
+#define GL_TEXTURE9 0x84C9
+#endif
+#ifndef GL_TEXTURE_BINDING_2D
+#define GL_TEXTURE_BINDING_2D 0x8069
+#endif
+#ifndef GL_TEXTURE_BINDING_CUBE_MAP
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_X
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_X
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_Y
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_Z
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#endif
+#ifndef GL_TEXTURE_MAG_FILTER
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#endif
+#ifndef GL_TEXTURE_MIN_FILTER
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#endif
+#ifndef GL_TEXTURE_WRAP_S
+#define GL_TEXTURE_WRAP_S 0x2802
+#endif
+#ifndef GL_TEXTURE_WRAP_T
+#define GL_TEXTURE_WRAP_T 0x2803
+#endif
+#ifndef GL_TRIANGLE_FAN
+#define GL_TRIANGLE_FAN 0x0006
+#endif
+#ifndef GL_TRIANGLES
+#define GL_TRIANGLES 0x0004
+#endif
+#ifndef GL_TRIANGLE_STRIP
+#define GL_TRIANGLE_STRIP 0x0005
+#endif
+#ifndef GL_TRUE
+#define GL_TRUE 1
+#endif
+#ifndef GL_UNPACK_ALIGNMENT
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#endif
+#ifndef GL_UNSIGNED_BYTE
+#define GL_UNSIGNED_BYTE 0x1401
+#endif
+#ifndef GL_UNSIGNED_INT
+#define GL_UNSIGNED_INT 0x1405
+#endif
+#ifndef GL_UNSIGNED_SHORT
+#define GL_UNSIGNED_SHORT 0x1403
+#endif
+#ifndef GL_UNSIGNED_SHORT_4_4_4_4
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_5_5_1
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_6_5
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#endif
+#ifndef GL_VALIDATE_STATUS
+#define GL_VALIDATE_STATUS 0x8B83
+#endif
+#ifndef GL_VENDOR
+#define GL_VENDOR 0x1F00
+#endif
+#ifndef GL_VERSION
+#define GL_VERSION 0x1F02
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_ENABLED
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_POINTER
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_SIZE
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_STRIDE
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_TYPE
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#endif
+#ifndef GL_VERTEX_SHADER
+#define GL_VERTEX_SHADER 0x8B31
+#endif
+#ifndef GL_VIEWPORT
+#define GL_VIEWPORT 0x0BA2
+#endif
+#ifndef GL_ZERO
+#define GL_ZERO 0
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 994947be4f..2ec345da57 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -76,6 +76,14 @@
\endlist
+
+ \section Threading
+
+ As of Qt 4.8, it's possible to render into a QGLPixelBuffer using
+ a QPainter in a separate thread. Note that OpenGL 2.0 or OpenGL ES
+ 2.0 is required for this to work. Also, under X11, it's necessary
+ to set the Qt::AA_X11InitThreads application attribute.
+
Pbuffers are provided by the OpenGL \c pbuffer extension; call
hasOpenGLPbuffer() to find out if the system provides pbuffers.
@@ -394,25 +402,25 @@ bool QGLPixelBuffer::isValid() const
}
#if !defined(QT_OPENGL_ES_1)
-Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine)
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
#endif
#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine)
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
#endif
/*! \reimp */
QPaintEngine *QGLPixelBuffer::paintEngine() const
{
#if defined(QT_OPENGL_ES_1)
- return qt_buffer_engine();
+ return qt_buffer_engine()->engine();
#elif defined(QT_OPENGL_ES_2)
- return qt_buffer_2_engine();
+ return qt_buffer_2_engine()->engine();
#else
if (qt_gl_preferGL2Engine())
- return qt_buffer_2_engine();
+ return qt_buffer_2_engine()->engine();
else
- return qt_buffer_engine();
+ return qt_buffer_engine()->engine();
#endif
}
diff --git a/src/opengl/qglpixelbuffer_win.cpp b/src/opengl/qglpixelbuffer_win.cpp
index b55f3836a0..1da0aad294 100644
--- a/src/opengl/qglpixelbuffer_win.cpp
+++ b/src/opengl/qglpixelbuffer_win.cpp
@@ -242,8 +242,7 @@ static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f
bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
- QGLWidget dmy;
- dmy.makeCurrent(); // needed for wglGetProcAddress() to succeed
+ QGLTemporaryContext tempContext;
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB =
(PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
@@ -257,7 +256,7 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge
if (!wglCreatePbufferARB) // assumes that if one can be resolved, all of them can
return false;
- dc = GetDC(dmy.winId());
+ dc = wglGetCurrentDC();
Q_ASSERT(dc);
// sample buffers doesn't work in conjunction with the render_texture extension
@@ -292,7 +291,6 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge
if (num_formats == 0) {
qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer - giving up.");
- ReleaseDC(dmy.winId(), dc);
return false;
}
format = pfiToQGLFormat(dc, pixel_format);
@@ -311,12 +309,10 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge
has_render_texture = false;
if (!pbuf) {
qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height());
- ReleaseDC(dmy.winId(), dc);
return false;
}
}
- ReleaseDC(dmy.winId(), dc);
dc = wglGetPbufferDCARB(pbuf);
ctx = wglCreateContext(dc);
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index bfa5ef180b..68586c141c 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -315,7 +315,7 @@ class QGLBlurTextureCache : public QObject
public:
static QGLBlurTextureCache *cacheForContext(const QGLContext *context);
- QGLBlurTextureCache();
+ QGLBlurTextureCache(const QGLContext *);
~QGLBlurTextureCache();
QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap);
@@ -336,15 +336,9 @@ private:
};
QList<QGLBlurTextureCache *> QGLBlurTextureCache::blurTextureCaches;
+Q_GLOBAL_STATIC(QGLContextGroupResource<QGLBlurTextureCache>, qt_blur_texture_caches)
-static void QGLBlurTextureCache_free(void *ptr)
-{
- delete reinterpret_cast<QGLBlurTextureCache *>(ptr);
-}
-
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_blur_texture_caches, (QGLBlurTextureCache_free))
-
-QGLBlurTextureCache::QGLBlurTextureCache()
+QGLBlurTextureCache::QGLBlurTextureCache(const QGLContext *)
: timerId(0)
{
cache.setMaxCost(4 * 1024 * 1024);
@@ -366,12 +360,7 @@ void QGLBlurTextureCache::timerEvent(QTimerEvent *)
QGLBlurTextureCache *QGLBlurTextureCache::cacheForContext(const QGLContext *context)
{
- QGLBlurTextureCache *p = reinterpret_cast<QGLBlurTextureCache *>(qt_blur_texture_caches()->value(context));
- if (!p) {
- p = new QGLBlurTextureCache;
- qt_blur_texture_caches()->insert(context, p);
- }
- return p;
+ return qt_blur_texture_caches()->value(context);
}
QGLBlurTextureInfo *QGLBlurTextureCache::takeBlurTextureInfo(const QPixmap &pixmap)
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp
index ef0160cd93..e97ade89f9 100644
--- a/src/openvg/qvg_symbian.cpp
+++ b/src/openvg/qvg_symbian.cpp
@@ -77,7 +77,8 @@ extern int qt_vg_pixmap_serial;
static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
{
- CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);
+ CFbsBitmap *copy = new CFbsBitmap;
+ Q_CHECK_PTR(copy);
if(!copy)
return 0;
@@ -228,7 +229,8 @@ void* QVGPixmapData::toNativeType(NativeType type)
sgInfo.iSizeInPixels.SetSize(w, h);
sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
- RSgImage *sgImage = q_check_ptr(new RSgImage());
+ RSgImage *sgImage = new RSgImage();
+ Q_CHECK_PTR(sgImage);
err = sgImage->Create(sgInfo, NULL, NULL);
if (err != KErrNone) {
driver.Close();
@@ -270,7 +272,8 @@ void* QVGPixmapData::toNativeType(NativeType type)
return reinterpret_cast<void*>(sgImage);
#endif
} else if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
+ CFbsBitmap *bitmap = new CFbsBitmap;
+ Q_CHECK_PTR(bitmap);
if (bitmap) {
if (bitmap->Create(TSize(source.width(), source.height()),
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index 662663d912..6eb0617a0e 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -348,7 +348,7 @@ QVariant QAccessibleTextEdit::invokeMethodEx(QAccessible::Method method, int chi
case ListSupportedMethods: {
QSet<QAccessible::Method> set;
set << ListSupportedMethods << SetCursorPosition << GetCursorPosition;
- return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
}
case SetCursorPosition:
diff --git a/src/plugins/accessible/widgets/rangecontrols.cpp b/src/plugins/accessible/widgets/rangecontrols.cpp
index 4cd171bb70..bf7b561e77 100644
--- a/src/plugins/accessible/widgets/rangecontrols.cpp
+++ b/src/plugins/accessible/widgets/rangecontrols.cpp
@@ -233,7 +233,7 @@ QVariant QAccessibleAbstractSpinBox::invokeMethodEx(Method method, int child, co
case ListSupportedMethods: {
QSet<QAccessible::Method> set;
set << ListSupportedMethods;
- return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
}
default:
@@ -814,7 +814,7 @@ QVariant QAccessibleAbstractSlider::invokeMethodEx(Method method, int child, con
case ListSupportedMethods: {
QSet<QAccessible::Method> set;
set << ListSupportedMethods;
- return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
}
default:
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index f39d5389f5..d8b57afa13 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -732,7 +732,7 @@ QVariant QAccessibleLineEdit::invokeMethodEx(QAccessible::Method method, int chi
case ListSupportedMethods: {
QSet<QAccessible::Method> set;
set << ListSupportedMethods << SetCursorPosition << GetCursorPosition;
- return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
}
case SetCursorPosition:
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
index 549a07a7a1..e94ae5ddc7 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp
+++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
@@ -1050,7 +1050,7 @@ QVariantMap QConnmanDeviceInterface::getProperties()
bool QConnmanDeviceInterface::setProperty(const QString &name, const QDBusVariant &value)
{
- QDBusMessage reply = this->call(QLatin1String("SetProperty"),name, qVariantFromValue(value));
+ QDBusMessage reply = this->call(QLatin1String("SetProperty"),name, QVariant::fromValue(value));
return true;
}
@@ -1112,7 +1112,7 @@ quint16 QConnmanDeviceInterface::getScanInterval()
bool QConnmanDeviceInterface::setScanInterval(const QString & interval)
{
// QList<QVariant> args;
-// args << qVariantFromValue(name)
+// args << QVariant::fromValue(name)
// << value.variant();
// QDBusMessage reply = this->callWithArgumentList(QDBus::AutoDetect,QLatin1String("SetProperty"),args);
@@ -1135,8 +1135,8 @@ QStringList QConnmanDeviceInterface::getNetworks()
bool QConnmanDeviceInterface::setEnabled(bool powered)
{
QList<QVariant> args;
- args << qVariantFromValue(QString("Powered"))
- << qVariantFromValue(QDBusVariant(powered));
+ args << QVariant::fromValue(QString("Powered"))
+ << QVariant::fromValue(QDBusVariant(powered));
QDBusMessage reply = this->callWithArgumentList(QDBus::AutoDetect,QLatin1String("SetProperty"),args);
return true;
diff --git a/src/plugins/gfxdrivers/eglnullws/README b/src/plugins/gfxdrivers/eglnullws/README
new file mode 100644
index 0000000000..80b88c7e01
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/README
@@ -0,0 +1,48 @@
+EGL NullWS QScreen Driver
+=========================
+
+If your application draws everything within a single full-screen QGLWidget then
+you may wish to use this QScreen plugin driver. This driver simply returns 0
+(as a EGLNativeWindowType value) when asked by the QtOpenGl module to create a
+native window. Some OpenGL ES implementations (including PowerVR) interpret this
+to mean that a full-screen OpenGL context is desired without any windowing
+support (NullWS).
+
+To tell a Qt/Embedded application to use this driver use the -display command
+line option or the QWS_DISPLAY environment variable. The following driver
+options are supported:
+
+size=WIDTHxHEIGHT Screen size reported by the driver
+format=FORMAT Screen format
+
+Run with '-display eglnullws:help' to get a full list of options (including a
+list of supported format strings).
+
+If you choose a screen format that is not supported by the hardware then the
+QtOpenGl module will write out a list of supported EGL configurations. Use
+one of the supported screen formats from this list.
+
+Using this driver with PowerVR hardware
+---------------------------------------
+
+Using this plugin with PowerVR hardware should give a significant speedup
+compared to running with the Qt powervr driver (with a full-screen QGLWidget).
+This is because sacrificing the window system allows less work to be done in
+order to get graphics on the screen. Using this driver also avoids the memory
+fragmentation issues present in the powervr driver and avoids any direct
+dependencies on the deprecated PVR2D API from Imagination Technologies.
+
+To use this driver ensure you have /etc/powervr.ini with contents similar to
+this:
+
+[default]
+WindowSystem=libpvrPVR2D_FLIPWSEGL.so
+
+This driver will also function with libpvrPVR2D_FRONTWSEGL.so, but that draws
+straight into the framebuffer and will therefore cause flickering (it can be
+useful for performance testing though). The flip plugin uses triple buffering,
+so you will need to set the virtual vertical resolution of your framebuffer to
+be three times the physical vertical resolution of your screen. This can be
+done with 'fbset -vyres'. Failure to do this can cause system crashes. You
+should also ensure that the plugin you choose in powervr.ini is in your library
+path (it may just silently default to the flip plugin if not).
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullws.pro b/src/plugins/gfxdrivers/eglnullws/eglnullws.pro
new file mode 100644
index 0000000000..242ab07ecd
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/eglnullws.pro
@@ -0,0 +1,18 @@
+TARGET = qeglnullws
+include(../../qpluginbase.pri)
+
+CONFIG += warn_on
+QT += opengl
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers
+
+target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
+INSTALLS += target
+
+HEADERS = eglnullwsscreen.h \
+ eglnullwsscreenplugin.h \
+ eglnullwswindowsurface.h
+
+SOURCES = eglnullwsscreen.cpp \
+ eglnullwsscreenplugin.cpp \
+ eglnullwswindowsurface.cpp
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp
new file mode 100644
index 0000000000..b8ea5d5c9e
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All 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 "eglnullwsscreen.h"
+#include "eglnullwswindowsurface.h"
+#include "eglnullwsscreenplugin.h"
+
+#include <QHash>
+#include <QDebug>
+
+namespace
+{
+ class EGLNullWSScreenSurfaceFunctions : public QGLScreenSurfaceFunctions
+ {
+ public:
+ virtual bool createNativeWindow(QWidget *, EGLNativeWindowType *native)
+ { *native = 0; return true; }
+ };
+}
+
+EGLNullWSScreen::EGLNullWSScreen(int displayId) : QGLScreen(displayId) {}
+
+EGLNullWSScreen::~EGLNullWSScreen() {}
+
+bool EGLNullWSScreen::initDevice()
+{
+ setSurfaceFunctions(new EGLNullWSScreenSurfaceFunctions);
+ return true;
+}
+
+static const QHash<QString, QImage::Format> formatDictionary()
+{
+ QHash<QString, QImage::Format> dictionary;
+ dictionary["rgb32"] = QImage::Format_RGB32;
+ dictionary["argb32"] = QImage::Format_ARGB32;
+ dictionary["rgb16"] = QImage::Format_RGB16;
+ dictionary["rgb666"] = QImage::Format_RGB666;
+ dictionary["rgb555"] = QImage::Format_RGB555;
+ dictionary["rgb888"] = QImage::Format_RGB888;
+ dictionary["rgb444"] = QImage::Format_RGB444;
+ return dictionary;
+}
+
+static int depthForFormat(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB32: return 32;
+ case QImage::Format_ARGB32: return 32;
+ case QImage::Format_RGB16: return 16;
+ case QImage::Format_RGB666: return 24;
+ case QImage::Format_RGB555: return 16;
+ case QImage::Format_RGB888: return 24;
+ case QImage::Format_RGB444: return 16;
+ default:
+ Q_ASSERT_X(false, "EGLNullWSScreen", "Unknown format");
+ return -1;
+ }
+}
+
+static void printHelp(const QHash<QString, QImage::Format> &formatDictionary)
+{
+ QByteArray formatsBuf;
+ QTextStream(&formatsBuf) << QStringList(formatDictionary.keys()).join(", ");
+ qWarning(
+ "%s: Valid options are:\n"
+ "size=WIDTHxHEIGHT Screen size reported by this driver\n"
+ "format=FORMAT Screen format, where FORMAT is one of the following:\n"
+ " %s\n",
+ PluginName,
+ formatsBuf.constData());
+}
+
+bool EGLNullWSScreen::connect(const QString &displaySpec)
+{
+ const QStringList args = displaySpec.section(':', 1).split(':', QString::SkipEmptyParts);
+ const QHash<QString, QImage::Format> formatDict = formatDictionary();
+ Q_FOREACH(const QString arg, args) {
+ const QString optionName = arg.section('=', 0, 0);
+ const QString optionArg = arg.section('=', 1);
+ if (optionName == QLatin1String("size")) {
+ w = optionArg.section('x', 0, 0).toInt();
+ h = optionArg.section('x', 1, 1).toInt();
+ } else if (optionName == QLatin1String("format")) {
+ if (formatDict.contains(optionArg))
+ setPixelFormat(formatDict.value(optionArg));
+ else
+ printHelp(formatDict);
+ } else {
+ printHelp(formatDict);
+ }
+ }
+
+ if (w == 0 || h == 0) {
+ w = 640;
+ h = 480;
+ qWarning("%s: Using default screen size %dx%d", PluginName, w, h);
+ }
+ dw = w;
+ dh = h;
+
+ if (pixelFormat() == QImage::Format_Invalid) {
+ qWarning("%s: Using default screen format argb32", PluginName);
+ setPixelFormat(QImage::Format_ARGB32);
+ }
+ d = depthForFormat(pixelFormat());
+
+ static const int Dpi = 120;
+ static const qreal ScalingFactor = static_cast<qreal>(25.4) / Dpi;
+ physWidth = qRound(dw * ScalingFactor);
+ physHeight = qRound(dh * ScalingFactor);
+
+ return true;
+}
+
+void EGLNullWSScreen::disconnect() {}
+
+void EGLNullWSScreen::shutdownDevice() {}
+
+void EGLNullWSScreen::setMode(int /*width*/, int /*height*/, int /*depth*/) {}
+
+void EGLNullWSScreen::blank(bool /*on*/) {}
+
+void EGLNullWSScreen::exposeRegion(QRegion /*r*/, int /*changing*/) {}
+
+QWSWindowSurface* EGLNullWSScreen::createSurface(QWidget *widget) const
+{
+ if (qobject_cast<QGLWidget*>(widget)) {
+ return new EGLNullWSWindowSurface(widget);
+ } else {
+ qWarning("%s: Creating non-GL surface", PluginName);
+ return QScreen::createSurface(widget);
+ }
+}
+
+QWSWindowSurface* EGLNullWSScreen::createSurface(const QString &key) const
+{
+ if (key == QLatin1String("eglnullws")) {
+ return new EGLNullWSWindowSurface;
+ } else {
+ qWarning("%s: Creating non-GL surface", PluginName);
+ return QScreen::createSurface(key);
+ }
+}
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h
new file mode 100644
index 0000000000..7f794bc047
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All 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 EGLNULLWSSCREEN
+#define EGLNULLWSSCREEN
+
+#include <QGLScreen>
+
+class EGLNullWSScreen : public QGLScreen
+{
+public:
+ EGLNullWSScreen(int displayId);
+ ~EGLNullWSScreen();
+
+ bool initDevice();
+ bool connect(const QString &displaySpec);
+ void disconnect();
+ void shutdownDevice();
+
+ void setMode(int width, int height, int depth);
+ void blank(bool on);
+
+ void exposeRegion(QRegion r, int changing);
+
+ QWSWindowSurface* createSurface(QWidget *widget) const;
+ QWSWindowSurface* createSurface(const QString &key) const;
+
+ bool hasOpenGL() { return true; }
+};
+
+#endif // EGLNULLWSSCREEN
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp
new file mode 100644
index 0000000000..67b3f56692
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All 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 "eglnullwsscreenplugin.h"
+#include "eglnullwsscreen.h"
+
+#include <QScreenDriverPlugin>
+#include <QStringList>
+
+class EGLNullWSScreenPlugin : public QScreenDriverPlugin
+{
+public:
+ virtual QStringList keys() const;
+ virtual QScreen *create(const QString& driver, int displayId);
+};
+
+QStringList EGLNullWSScreenPlugin::keys() const
+{
+ return QStringList() << QLatin1String(PluginName);
+}
+
+QScreen *EGLNullWSScreenPlugin::create(const QString& driver, int displayId)
+{
+ return (driver.toLower() == QLatin1String(PluginName) ?
+ new EGLNullWSScreen(displayId) : 0);
+}
+
+Q_EXPORT_PLUGIN2(qeglnullws, EGLNullWSScreenPlugin)
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h
new file mode 100644
index 0000000000..84f06991fa
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All 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 EGLNULLWSSCREENPLUGIN_H
+#define EGLNULLWSSCREENPLUGIN_H
+
+const char *const PluginName = "eglnullws";
+
+#endif // EGLNULLWSSCREENPLUGIN_H
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp
new file mode 100644
index 0000000000..da4b728ecd
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All 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 "eglnullwswindowsurface.h"
+#include "eglnullwsscreenplugin.h"
+
+#include <QGLWidget>
+
+static const QWSWindowSurface::SurfaceFlags Flags
+ = QWSWindowSurface::RegionReserved | QWSWindowSurface::RegionReserved;
+
+EGLNullWSWindowSurface::EGLNullWSWindowSurface(QWidget *w)
+ :
+ QWSGLWindowSurface(w),
+ widget(w)
+{
+ setSurfaceFlags(Flags);
+}
+
+EGLNullWSWindowSurface::EGLNullWSWindowSurface()
+ : widget(0)
+{
+ setSurfaceFlags(Flags);
+}
+
+EGLNullWSWindowSurface::~EGLNullWSWindowSurface() {}
+
+QString EGLNullWSWindowSurface::key() const
+{
+ return QLatin1String(PluginName);
+}
+
+QPaintDevice *EGLNullWSWindowSurface::paintDevice()
+{
+ return widget;
+}
+
+bool EGLNullWSWindowSurface::isValid() const
+{
+ return qobject_cast<QGLWidget *>(window());
+}
+
+QImage EGLNullWSWindowSurface::image() const
+{
+ return QImage();
+}
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h b/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h
new file mode 100644
index 0000000000..b730415fe7
--- /dev/null
+++ b/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All 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 EGLNULLWSWINDOWSURFACE_H
+#define EGLNULLWSWINDOWSURFACE_H
+
+#include <private/qglwindowsurface_qws_p.h>
+
+class EGLNullWSWindowSurface : public QWSGLWindowSurface
+{
+public:
+ EGLNullWSWindowSurface(QWidget *widget);
+ EGLNullWSWindowSurface();
+ virtual ~EGLNullWSWindowSurface();
+
+ virtual QString key() const;
+ virtual QPaintDevice *paintDevice();
+ virtual bool isValid() const;
+ virtual QImage image() const;
+
+private:
+ QWidget *widget;
+};
+
+#endif // EGLNULLWSWINDOWSURFACE_H
diff --git a/src/plugins/gfxdrivers/gfxdrivers.pro b/src/plugins/gfxdrivers/gfxdrivers.pro
index d1ee3f2704..1f38942a50 100644
--- a/src/plugins/gfxdrivers/gfxdrivers.pro
+++ b/src/plugins/gfxdrivers/gfxdrivers.pro
@@ -7,3 +7,4 @@ contains(gfx-plugins, vnc) :SUBDIRS += vnc
contains(gfx-plugins, transformed) :SUBDIRS += transformed
contains(gfx-plugins, svgalib) :SUBDIRS += svgalib
contains(gfx-plugins, powervr) :SUBDIRS += powervr
+contains(gfx-plugins, eglnullws) :SUBDIRS += eglnullws
diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri
index 8b119b5580..45e3976f33 100644
--- a/src/plugins/qpluginbase.pri
+++ b/src/plugins/qpluginbase.pri
@@ -1,6 +1,6 @@
TEMPLATE = lib
isEmpty(QT_MAJOR_VERSION) {
- VERSION=4.7.0
+ VERSION=4.8.0
} else {
VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
}
diff --git a/src/qbase.pri b/src/qbase.pri
index f6af22f481..aa7d745269 100644
--- a/src/qbase.pri
+++ b/src/qbase.pri
@@ -4,7 +4,7 @@ INCLUDEPATH *= $$QMAKE_INCDIR_QT/$$TARGET #just for today to have some compat
isEmpty(QT_ARCH):!isEmpty(ARCH):QT_ARCH=$$ARCH #another compat that will rot for change #215700
TEMPLATE = lib
isEmpty(QT_MAJOR_VERSION) {
- VERSION=4.7.0
+ VERSION=4.8.0
} else {
VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
}
diff --git a/src/qt3support/text/q3richtext.cpp b/src/qt3support/text/q3richtext.cpp
index 86140769b8..625dd95ab2 100644
--- a/src/qt3support/text/q3richtext.cpp
+++ b/src/qt3support/text/q3richtext.cpp
@@ -8079,9 +8079,9 @@ bool Q3TextTable::down(Q3TextCursor *c, Q3TextDocument *&doc, Q3TextParagraph *&
break;
}
}
- doc = cell->richText();
if (!cell)
return false;
+ doc = cell->richText();
parag = doc->firstParagraph();
idx = 0;
ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
@@ -8117,9 +8117,9 @@ bool Q3TextTable::up(Q3TextCursor *c, Q3TextDocument *&doc, Q3TextParagraph *&pa
break;
}
}
- doc = cell->richText();
if (!cell)
return false;
+ doc = cell->richText();
parag = doc->lastParagraph();
idx = parag->length() - 1;
ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
diff --git a/src/qt3support/text/q3textstream.h b/src/qt3support/text/q3textstream.h
index d0c4f48aab..0e26e08499 100644
--- a/src/qt3support/text/q3textstream.h
+++ b/src/qt3support/text/q3textstream.h
@@ -272,13 +272,13 @@ private:
int arg; // member function argument
};
-Q_COMPAT_EXPORT inline Q3TextStream &operator>>( Q3TextStream &s, Q3TSFUNC f )
+Q_COMPAT_EXPORT_INLINE Q3TextStream &operator>>( Q3TextStream &s, Q3TSFUNC f )
{ return (*f)( s ); }
-Q_COMPAT_EXPORT inline Q3TextStream &operator<<( Q3TextStream &s, Q3TSFUNC f )
+Q_COMPAT_EXPORT_INLINE Q3TextStream &operator<<( Q3TextStream &s, Q3TSFUNC f )
{ return (*f)( s ); }
-Q_COMPAT_EXPORT inline Q3TextStream &operator<<( Q3TextStream &s, Q3TSManip m )
+Q_COMPAT_EXPORT_INLINE Q3TextStream &operator<<( Q3TextStream &s, Q3TSManip m )
{ m.exec(s); return s; }
Q_COMPAT_EXPORT Q3TextStream &bin( Q3TextStream &s ); // set bin notation
diff --git a/src/qt3support/tools/q3cstring.h b/src/qt3support/tools/q3cstring.h
index b280ebc122..86a31fa157 100644
--- a/src/qt3support/tools/q3cstring.h
+++ b/src/qt3support/tools/q3cstring.h
@@ -161,75 +161,75 @@ inline Q3CString &Q3CString::setNum(float n, char f, int prec)
Q3CString non-member operators
*****************************************************************************/
-Q_COMPAT_EXPORT inline bool operator==(const Q3CString &s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator==(const Q3CString &s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) == 0; }
-Q_COMPAT_EXPORT inline bool operator==(const Q3CString &s1, const char *s2)
+Q_COMPAT_EXPORT_INLINE bool operator==(const Q3CString &s1, const char *s2)
{ return qstrcmp(s1, s2) == 0; }
-Q_COMPAT_EXPORT inline bool operator==(const char *s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator==(const char *s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) == 0; }
-Q_COMPAT_EXPORT inline bool operator!=(const Q3CString &s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator!=(const Q3CString &s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) != 0; }
-Q_COMPAT_EXPORT inline bool operator!=(const Q3CString &s1, const char *s2)
+Q_COMPAT_EXPORT_INLINE bool operator!=(const Q3CString &s1, const char *s2)
{ return qstrcmp(s1, s2) != 0; }
-Q_COMPAT_EXPORT inline bool operator!=(const char *s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator!=(const char *s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) != 0; }
-Q_COMPAT_EXPORT inline bool operator<(const Q3CString &s1, const Q3CString& s2)
+Q_COMPAT_EXPORT_INLINE bool operator<(const Q3CString &s1, const Q3CString& s2)
{ return qstrcmp(s1, s2) < 0; }
-Q_COMPAT_EXPORT inline bool operator<(const Q3CString &s1, const char *s2)
+Q_COMPAT_EXPORT_INLINE bool operator<(const Q3CString &s1, const char *s2)
{ return qstrcmp(s1, s2) < 0; }
-Q_COMPAT_EXPORT inline bool operator<(const char *s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator<(const char *s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) < 0; }
-Q_COMPAT_EXPORT inline bool operator<=(const Q3CString &s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator<=(const Q3CString &s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) <= 0; }
-Q_COMPAT_EXPORT inline bool operator<=(const Q3CString &s1, const char *s2)
+Q_COMPAT_EXPORT_INLINE bool operator<=(const Q3CString &s1, const char *s2)
{ return qstrcmp(s1, s2) <= 0; }
-Q_COMPAT_EXPORT inline bool operator<=(const char *s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator<=(const char *s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) <= 0; }
-Q_COMPAT_EXPORT inline bool operator>(const Q3CString &s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator>(const Q3CString &s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) > 0; }
-Q_COMPAT_EXPORT inline bool operator>(const Q3CString &s1, const char *s2)
+Q_COMPAT_EXPORT_INLINE bool operator>(const Q3CString &s1, const char *s2)
{ return qstrcmp(s1, s2) > 0; }
-Q_COMPAT_EXPORT inline bool operator>(const char *s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator>(const char *s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) > 0; }
-Q_COMPAT_EXPORT inline bool operator>=(const Q3CString &s1, const Q3CString& s2)
+Q_COMPAT_EXPORT_INLINE bool operator>=(const Q3CString &s1, const Q3CString& s2)
{ return qstrcmp(s1, s2) >= 0; }
-Q_COMPAT_EXPORT inline bool operator>=(const Q3CString &s1, const char *s2)
+Q_COMPAT_EXPORT_INLINE bool operator>=(const Q3CString &s1, const char *s2)
{ return qstrcmp(s1, s2) >= 0; }
-Q_COMPAT_EXPORT inline bool operator>=(const char *s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE bool operator>=(const char *s1, const Q3CString &s2)
{ return qstrcmp(s1, s2) >= 0; }
-Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1,
+Q_COMPAT_EXPORT_INLINE const Q3CString operator+(const Q3CString &s1,
const Q3CString &s2)
{
Q3CString tmp(s1);
tmp += s2;
return tmp;
}
-Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1,
+Q_COMPAT_EXPORT_INLINE const Q3CString operator+(const Q3CString &s1,
const QByteArray &s2)
{
QByteArray tmp(s1);
tmp += s2;
return tmp;
}
-Q_COMPAT_EXPORT inline const Q3CString operator+(const QByteArray &s1,
+Q_COMPAT_EXPORT_INLINE const Q3CString operator+(const QByteArray &s1,
const Q3CString &s2)
{
QByteArray tmp(s1);
@@ -237,28 +237,28 @@ Q_COMPAT_EXPORT inline const Q3CString operator+(const QByteArray &s1,
return tmp;
}
-Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1, const char *s2)
+Q_COMPAT_EXPORT_INLINE const Q3CString operator+(const Q3CString &s1, const char *s2)
{
Q3CString tmp(s1);
tmp += s2;
return tmp;
}
-Q_COMPAT_EXPORT inline const Q3CString operator+(const char *s1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE const Q3CString operator+(const char *s1, const Q3CString &s2)
{
Q3CString tmp(s1);
tmp += s2;
return tmp;
}
-Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1, char c2)
+Q_COMPAT_EXPORT_INLINE const Q3CString operator+(const Q3CString &s1, char c2)
{
Q3CString tmp(s1);
tmp += c2;
return tmp;
}
-Q_COMPAT_EXPORT inline const Q3CString operator+(char c1, const Q3CString &s2)
+Q_COMPAT_EXPORT_INLINE const Q3CString operator+(char c1, const Q3CString &s2)
{
Q3CString tmp;
tmp += c1;
diff --git a/src/s60main/qts60main.cpp b/src/s60main/qts60main.cpp
index 5fbeea5479..c65344bf65 100644
--- a/src/s60main/qts60main.cpp
+++ b/src/s60main/qts60main.cpp
@@ -51,7 +51,8 @@ GLDEF_C TInt QtMainWrapper();
*/
GLDEF_C TInt E32Main()
{
- CTrapCleanup *cleanupStack = q_check_ptr(CTrapCleanup::New());
+ CTrapCleanup *cleanupStack = CTrapCleanup::New();
+ Q_CHECK_PTR(cleanupStack);
TInt err = 0;
TRAP(err, err = QtMainWrapper());
delete cleanupStack;
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 07aced4372..0a669b531d 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -1730,7 +1730,7 @@ QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue valu
return variantValue(value);
#ifndef QT_NO_QOBJECT
else if (isQObject(value))
- return qVariantFromValue(toQObject(exec, value));
+ return QVariant::fromValue(toQObject(exec, value));
#endif
else if (isDate(value))
return QVariant(toDateTime(exec, value));
@@ -2454,10 +2454,6 @@ QScriptValue QScriptEngine::newQMetaObject(
\snippet doc/src/snippets/code/src_script_qscriptengine.cpp 13
- \warning This function is not available with MSVC 6. Use
- qScriptValueFromQMetaObject() instead if you need to support that version
- of the compiler.
-
\sa QScriptEngine::newQMetaObject()
*/
@@ -2465,14 +2461,17 @@ QScriptValue QScriptEngine::newQMetaObject(
\fn QScriptValue qScriptValueFromQMetaObject(QScriptEngine *engine)
\since 4.3
\relates QScriptEngine
+ \obsolete
Uses \a engine to create a QScriptValue that represents the Qt class
\c{T}.
This function is equivalent to
- QScriptEngine::scriptValueFromQMetaObject(). It is provided as a
- work-around for MSVC 6, which doesn't support member template
- functions.
+ QScriptEngine::scriptValueFromQMetaObject().
+
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
\sa QScriptEngine::newQMetaObject()
*/
@@ -3002,14 +3001,7 @@ JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const
case QMetaType::LongLong:
return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
case QMetaType::ULongLong:
-#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
-#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
- return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
-#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
-#else
return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
-#endif
case QMetaType::Double:
return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const double*>(ptr)));
case QMetaType::QString:
@@ -3053,7 +3045,7 @@ JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const
break;
#endif
case QMetaType::QVariant:
- result = jscValueFromVariant(exec, *reinterpret_cast<const QVariant*>(ptr));
+ result = eng->newVariant(*reinterpret_cast<const QVariant*>(ptr));
break;
default:
if (type == qMetaTypeId<QScriptValue>()) {
@@ -3771,10 +3763,6 @@ QStringList QScriptEngine::importedExtensions() const
to newVariant()); you can change this behavior by installing your
own type conversion functions with qScriptRegisterMetaType().
- \warning This function is not available with MSVC 6. Use
- qScriptValueFromValue() instead if you need to support that
- version of the compiler.
-
\sa fromScriptValue(), qScriptRegisterMetaType()
*/
@@ -3788,10 +3776,6 @@ QStringList QScriptEngine::importedExtensions() const
description of the built-in type conversion provided by
QtScript.
- \warning This function is not available with MSVC 6. Use
- qScriptValueToValue() or qscriptvalue_cast() instead if you need
- to support that version of the compiler.
-
\sa toScriptValue(), qScriptRegisterMetaType()
*/
@@ -3799,29 +3783,35 @@ QStringList QScriptEngine::importedExtensions() const
\fn QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &value)
\since 4.3
\relates QScriptEngine
+ \obsolete
Creates a QScriptValue using the given \a engine with the given \a
value of template type \c{T}.
This function is equivalent to QScriptEngine::toScriptValue().
- It is provided as a work-around for MSVC 6, which doesn't support
- member template functions.
- \sa qScriptValueToValue()
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
+
+ \sa QScriptEngine::toScriptValue(), qscriptvalue_cast
*/
/*!
\fn T qScriptValueToValue(const QScriptValue &value)
\since 4.3
\relates QScriptEngine
+ \obsolete
Returns the given \a value converted to the template type \c{T}.
This function is equivalent to QScriptEngine::fromScriptValue().
- It is provided as a work-around for MSVC 6, which doesn't
- support member template functions.
- \sa qScriptValueFromValue()
+ \note This function was provided as a workaround for MSVC 6
+ which did not support member template functions. It is advised
+ to use the other form in new code.
+
+ \sa QScriptEngine::fromScriptValue()
*/
/*!
@@ -3840,7 +3830,7 @@ QStringList QScriptEngine::importedExtensions() const
\l{Conversion Between QtScript and C++ Types} for more information
about the restrictions on types that can be used with QScriptValue.
- \sa qScriptValueFromValue()
+ \sa QScriptEngine::fromScriptValue()
*/
/*!
diff --git a/src/script/api/qscriptengine.h b/src/script/api/qscriptengine.h
index 3212ed54a4..830d477b77 100644
--- a/src/script/api/qscriptengine.h
+++ b/src/script/api/qscriptengine.h
@@ -65,13 +65,11 @@ inline QScriptValue qscriptQMetaObjectConstructor(QScriptContext *, QScriptEngin
class QRegExp;
#endif
-#ifndef QT_NO_MEMBER_TEMPLATES
template <typename T>
inline QScriptValue qScriptValueFromValue(QScriptEngine *, const T &);
template <typename T>
-inline T qScriptValueToValue(const QScriptValue &);
-#endif
+inline T qscriptvalue_cast(const QScriptValue &);
class QScriptSyntaxCheckResultPrivate;
class Q_SCRIPT_EXPORT QScriptSyntaxCheckResult
@@ -196,9 +194,7 @@ public:
QScriptValue newQMetaObject(const QMetaObject *metaObject, const QScriptValue &ctor = QScriptValue());
-# ifndef QT_NO_MEMBER_TEMPLATES
template <class T> QScriptValue scriptValueFromQMetaObject();
-# endif // QT_NO_MEMBER_TEMPLATES
#endif // QT_NO_QOBJECT
@@ -213,7 +209,6 @@ public:
-#ifndef QT_NO_MEMBER_TEMPLATES
template <typename T>
inline QScriptValue toScriptValue(const T &value)
{
@@ -222,9 +217,8 @@ public:
template <typename T>
inline T fromScriptValue(const QScriptValue &value)
{
- return qScriptValueToValue<T>(value);
+ return qscriptvalue_cast<T>(value);
}
-#endif // QT_NO_MEMBER_TEMPLATES
void installTranslatorFunctions(const QScriptValue &object = QScriptValue());
@@ -285,19 +279,6 @@ private:
};
#ifndef QT_NO_QOBJECT
-template <class T>
-inline QScriptValue qScriptValueFromQMetaObject(
- QScriptEngine *engine
-#ifndef qdoc
- , T * /* dummy */ = 0
-#endif
- )
-{
- typedef QScriptValue(*ConstructPtr)(QScriptContext *, QScriptEngine *, T *);
- ConstructPtr cptr = qscriptQMetaObjectConstructor<T>;
- return engine->newQMetaObject(&T::staticMetaObject,
- engine->newFunction(reinterpret_cast<QScriptEngine::FunctionWithArgSignature>(cptr), 0));
-}
#define Q_SCRIPT_DECLARE_QMETAOBJECT(T, _Arg1) \
template<> inline QScriptValue qscriptQMetaObjectConstructor<T>(QScriptContext *ctx, QScriptEngine *eng, T *) \
@@ -311,12 +292,26 @@ template<> inline QScriptValue qscriptQMetaObjectConstructor<T>(QScriptContext *
return o; \
}
-# ifndef QT_NO_MEMBER_TEMPLATES
- template <class T> QScriptValue QScriptEngine::scriptValueFromQMetaObject()
- {
- return qScriptValueFromQMetaObject<T>(this);
- }
-# endif // QT_NO_MEMBER_TEMPLATES
+template <class T> QScriptValue QScriptEngine::scriptValueFromQMetaObject()
+{
+ typedef QScriptValue(*ConstructPtr)(QScriptContext *, QScriptEngine *, T *);
+ ConstructPtr cptr = qscriptQMetaObjectConstructor<T>;
+ return newQMetaObject(&T::staticMetaObject,
+ newFunction(reinterpret_cast<FunctionWithArgSignature>(cptr), 0));
+}
+
+#ifdef QT_DEPRECATED
+template <class T>
+inline QT_DEPRECATED QScriptValue qScriptValueFromQMetaObject(
+ QScriptEngine *engine
+#ifndef qdoc
+ , T * /* dummy */ = 0
+#endif
+ )
+{
+ return engine->scriptValueFromQMetaObject<T>();
+}
+#endif
#endif // QT_NO_QOBJECT
@@ -349,11 +344,7 @@ inline bool qscriptvalue_cast_helper(const QScriptValue &value, int type, void *
}
template<typename T>
-T qscriptvalue_cast(const QScriptValue &value
-#if !defined qdoc && defined Q_CC_MSVC && _MSC_VER < 1300
-, T * = 0
-#endif
- )
+T qscriptvalue_cast(const QScriptValue &value)
{
T t;
const int id = qMetaTypeId<T>();
@@ -366,19 +357,19 @@ T qscriptvalue_cast(const QScriptValue &value
return T();
}
-#if !defined Q_CC_MSVC || _MSC_VER >= 1300
template <>
inline QVariant qscriptvalue_cast<QVariant>(const QScriptValue &value)
{
return value.toVariant();
}
-#endif
+#ifdef QT_DEPRECATED
template <typename T>
-inline T qScriptValueToValue(const QScriptValue &value)
+inline QT_DEPRECATED T qScriptValueToValue(const QScriptValue &value)
{
return qscriptvalue_cast<T>(value);
}
+#endif
inline void qScriptRegisterMetaType_helper(QScriptEngine *eng, int type,
QScriptEngine::MarshalFunction mf,
@@ -418,7 +409,7 @@ QScriptValue qScriptValueFromSequence(QScriptEngine *eng, const Container &cont)
typename Container::const_iterator it;
quint32 i;
for (it = begin, i = 0; it != end; ++it, ++i)
- a.setProperty(i, qScriptValueFromValue(eng, *it));
+ a.setProperty(i, eng->toScriptValue(*it));
return a;
}
@@ -428,11 +419,7 @@ void qScriptValueToSequence(const QScriptValue &value, Container &cont)
quint32 len = value.property(QLatin1String("length")).toUInt32();
for (quint32 i = 0; i < len; ++i) {
QScriptValue item = value.property(i);
-#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET
- cont.push_back(qscriptvalue_cast<Container::value_type>(item));
-#else
cont.push_back(qscriptvalue_cast<typename Container::value_type>(item));
-#endif
}
}
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index f6390bb0be..fbd5d96925 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -688,10 +688,6 @@ static bool LessThan(QScriptValue lhs, QScriptValue rhs)
return false;
case Number:
-#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET
- if (qIsNaN(lhs.toNumber()) || qIsNaN(rhs.toNumber()))
- return false;
-#endif
return lhs.toNumber() < rhs.toNumber();
case Boolean:
@@ -714,13 +710,7 @@ static bool LessThan(QScriptValue lhs, QScriptValue rhs)
if (lhs.isString() && rhs.isString())
return lhs.toString() < rhs.toString();
- qsreal n1 = lhs.toNumber();
- qsreal n2 = rhs.toNumber();
-#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET
- if (qIsNaN(n1) || qIsNaN(n2))
- return false;
-#endif
- return n1 < n2;
+ return lhs.toNumber() < rhs.toNumber();
}
static bool Equals(QScriptValue lhs, QScriptValue rhs)
diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp
index dd229f1fa4..28f7bd12e9 100644
--- a/src/script/bridge/qscriptclassobject.cpp
+++ b/src/script/bridge/qscriptclassobject.cpp
@@ -211,7 +211,7 @@ JSC::JSValue JSC_HOST_CALL ClassObjectDelegate::call(JSC::ExecState *exec, JSC::
eng_p->pushContext(exec, thisValue, args, callee);
QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj);
- QVariant result = scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx));
+ QVariant result = scriptClass->extension(QScriptClass::Callable, QVariant::fromValue(ctx));
eng_p->popContext();
eng_p->currentFrame = oldFrame;
return QScriptEnginePrivate::jscValueFromVariant(exec, result);
@@ -239,7 +239,7 @@ JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObjec
QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
QScriptValue defaultObject = ctx->thisObject();
- QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx)));
+ QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, QVariant::fromValue(ctx)));
if (!result.isObject())
result = defaultObject;
eng_p->popContext();
@@ -256,7 +256,7 @@ bool ClassObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState *exe
QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
QScript::SaveFrameHelper saveFrame(eng_p, exec);
args << eng_p->scriptValueFromJSCValue(object) << eng_p->scriptValueFromJSCValue(value);
- QVariant result = scriptClass()->extension(QScriptClass::HasInstance, qVariantFromValue(args));
+ QVariant result = scriptClass()->extension(QScriptClass::HasInstance, QVariant::fromValue(args));
return result.toBool();
}
diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp
index 5e4f097e1f..d24f2fe04b 100644
--- a/src/script/bridge/qscriptqobject.cpp
+++ b/src/script/bridge/qscriptqobject.cpp
@@ -664,7 +664,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c
if (actual.isNumber()) {
int ival = QScriptEnginePrivate::toInt32(exec, actual);
if (m.valueToKey(ival) != 0) {
- qVariantSetValue(v, ival);
+ v.setValue(ival);
converted = true;
matchDistance += 10;
}
@@ -672,7 +672,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c
JSC::UString sval = QScriptEnginePrivate::toString(exec, actual);
int ival = m.keyToValue(convertToLatin1(sval));
if (ival != -1) {
- qVariantSetValue(v, ival);
+ v.setValue(ival);
converted = true;
matchDistance += 10;
}
@@ -1668,7 +1668,7 @@ static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChild(JSC::ExecState *exec
QString name;
if (args.size() != 0)
name = args.at(0).toString(exec);
- QObject *child = qFindChild<QObject*>(obj, name);
+ QObject *child = obj->findChild<QObject*>(name);
QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject;
return engine->newQObject(child, QScriptEngine::QtOwnership, opt);
}
@@ -1709,10 +1709,10 @@ static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChildren(JSC::ExecState *e
}
} else {
const QString name(args.at(0).toString(exec));
- children = qFindChildren<QObject*>(obj, name);
+ children = obj->findChildren<QObject*>(name);
}
} else {
- children = qFindChildren<QObject*>(obj, QString());
+ children = obj->findChildren<QObject*>(QString());
}
// create the result array with the children
const int length = children.size();
diff --git a/src/scripttools/debugging/qscriptdebuggercommand.cpp b/src/scripttools/debugging/qscriptdebuggercommand.cpp
index fa223ecf57..5ca0535cde 100644
--- a/src/scripttools/debugging/qscriptdebuggercommand.cpp
+++ b/src/scripttools/debugging/qscriptdebuggercommand.cpp
@@ -256,7 +256,7 @@ QScriptBreakpointData QScriptDebuggerCommand::breakpointData() const
void QScriptDebuggerCommand::setBreakpointData(const QScriptBreakpointData &data)
{
Q_D(QScriptDebuggerCommand);
- d->attributes[BreakpointData] = qVariantFromValue(data);
+ d->attributes[BreakpointData] = QVariant::fromValue(data);
}
QScriptDebuggerValue QScriptDebuggerCommand::scriptValue() const
@@ -268,7 +268,7 @@ QScriptDebuggerValue QScriptDebuggerCommand::scriptValue() const
void QScriptDebuggerCommand::setScriptValue(const QScriptDebuggerValue &value)
{
Q_D(QScriptDebuggerCommand);
- d->attributes[ScriptValue] = qVariantFromValue(value);
+ d->attributes[ScriptValue] = QVariant::fromValue(value);
}
int QScriptDebuggerCommand::contextIndex() const
@@ -316,7 +316,7 @@ QScriptDebuggerValue QScriptDebuggerCommand::subordinateScriptValue() const
void QScriptDebuggerCommand::setSubordinateScriptValue(const QScriptDebuggerValue &value)
{
Q_D(QScriptDebuggerCommand);
- d->attributes[SubordinateScriptValue] = qVariantFromValue(value);
+ d->attributes[SubordinateScriptValue] = QVariant::fromValue(value);
}
int QScriptDebuggerCommand::snapshotId() const
diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
index 568af59f0f..7616148e5e 100644
--- a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
+++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
@@ -229,11 +229,11 @@ QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
case QScriptDebuggerCommand::ScriptsCheckpoint:
backend->scriptsCheckpoint();
- response.setResult(qVariantFromValue(backend->scriptsDelta()));
+ response.setResult(QVariant::fromValue(backend->scriptsDelta()));
break;
case QScriptDebuggerCommand::GetScriptsDelta:
- response.setResult(qVariantFromValue(backend->scriptsDelta()));
+ response.setResult(QVariant::fromValue(backend->scriptsDelta()));
break;
case QScriptDebuggerCommand::ResolveScript:
@@ -302,7 +302,7 @@ QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
} break;
case QScriptDebuggerCommand::ContextsCheckpoint: {
- response.setResult(qVariantFromValue(backend->contextsCheckpoint()));
+ response.setResult(QVariant::fromValue(backend->contextsCheckpoint()));
} break;
case QScriptDebuggerCommand::GetPropertyExpressionValue: {
@@ -441,7 +441,7 @@ QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
result.addedProperties.append(dest);
}
backend->setIgnoreExceptions(didIgnoreExceptions);
- response.setResult(qVariantFromValue(result));
+ response.setResult(QVariant::fromValue(result));
} break;
case QScriptDebuggerCommand::DeleteScriptObjectSnapshot: {
diff --git a/src/scripttools/debugging/qscriptdebuggerconsole.cpp b/src/scripttools/debugging/qscriptdebuggerconsole.cpp
index 2f7a99833b..268b30e08e 100644
--- a/src/scripttools/debugging/qscriptdebuggerconsole.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerconsole.cpp
@@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE
static QScriptValue debuggerResponseToScriptValue(QScriptEngine *eng, const QScriptDebuggerResponse &in)
{
QScriptValue out = eng->newObject();
- out.setProperty(QString::fromLatin1("result"), qScriptValueFromValue(eng, in.result()));
+ out.setProperty(QString::fromLatin1("result"), eng->toScriptValue(in.result()));
out.setProperty(QString::fromLatin1("error"), QScriptValue(eng, in.error()));
out.setProperty(QString::fromLatin1("async"), QScriptValue(eng, in.async()));
return out;
@@ -122,7 +122,7 @@ static QScriptValue breakpointMapToScriptValue(QScriptEngine *eng, const QScript
QScriptValue out = eng->newObject();
QScriptBreakpointMap::const_iterator it;
for (it = in.constBegin(); it != in.constEnd(); ++it) {
- out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value()));
+ out.setProperty(QString::number(it.key()), eng->toScriptValue(it.value()));
}
return out;
}
@@ -155,7 +155,7 @@ static QScriptValue scriptMapToScriptValue(QScriptEngine *eng, const QScriptScri
QScriptValue out = eng->newObject();
QScriptScriptMap::const_iterator it;
for (it = in.constBegin(); it != in.constEnd(); ++it) {
- out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value()));
+ out.setProperty(QString::number(it.key()), eng->toScriptValue(it.value()));
}
return out;
}
@@ -175,8 +175,8 @@ static QScriptValue consoleCommandToScriptValue(
out.setProperty(QString::fromLatin1("group"), QScriptValue(eng, in->group()));
out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in->shortDescription()));
out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in->longDescription()));
- out.setProperty(QString::fromLatin1("aliases"), qScriptValueFromValue(eng, in->aliases()));
- out.setProperty(QString::fromLatin1("seeAlso"), qScriptValueFromValue(eng, in->seeAlso()));
+ out.setProperty(QString::fromLatin1("aliases"), eng->toScriptValue(in->aliases()));
+ out.setProperty(QString::fromLatin1("seeAlso"), eng->toScriptValue(in->seeAlso()));
return out;
}
@@ -207,7 +207,7 @@ static QScriptValue consoleCommandGroupMapToScriptValue(
QScriptValue out = eng->newObject();
QScriptDebuggerConsoleCommandGroupMap::const_iterator it;
for (it = in.constBegin(); it != in.constEnd(); ++it) {
- out.setProperty(it.key(), qScriptValueFromValue(eng, it.value()));
+ out.setProperty(it.key(), eng->toScriptValue(it.value()));
}
return out;
}
@@ -238,7 +238,7 @@ static QScriptValue debuggerScriptValuePropertyToScriptValue(QScriptEngine *eng,
{
QScriptValue out = eng->newObject();
out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in.name()));
- out.setProperty(QString::fromLatin1("value"), qScriptValueFromValue(eng, in.value()));
+ out.setProperty(QString::fromLatin1("value"), eng->toScriptValue(in.value()));
out.setProperty(QString::fromLatin1("valueAsString"), QScriptValue(eng, in.valueAsString()));
out.setProperty(QString::fromLatin1("flags"), QScriptValue(eng, static_cast<int>(in.flags())));
return out;
diff --git a/src/scripttools/debugging/qscriptdebuggerevent.cpp b/src/scripttools/debugging/qscriptdebuggerevent.cpp
index f5f20cf3cb..55df35b6ae 100644
--- a/src/scripttools/debugging/qscriptdebuggerevent.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerevent.cpp
@@ -216,7 +216,7 @@ QScriptDebuggerValue QScriptDebuggerEvent::scriptValue() const
void QScriptDebuggerEvent::setScriptValue(const QScriptDebuggerValue &value)
{
Q_D(QScriptDebuggerEvent);
- d->attributes[Value] = qVariantFromValue(value);
+ d->attributes[Value] = QVariant::fromValue(value);
}
void QScriptDebuggerEvent::setNestedEvaluate(bool nested)
diff --git a/src/scripttools/debugging/qscriptdebuggerresponse.cpp b/src/scripttools/debugging/qscriptdebuggerresponse.cpp
index 0caa3e2cab..382e604e44 100644
--- a/src/scripttools/debugging/qscriptdebuggerresponse.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerresponse.cpp
@@ -162,49 +162,49 @@ void QScriptDebuggerResponse::setResult(const QString &value)
void QScriptDebuggerResponse::setResult(const QScriptBreakpointData &data)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(data);
+ d->result = QVariant::fromValue(data);
}
void QScriptDebuggerResponse::setResult(const QScriptBreakpointMap &breakpoints)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(breakpoints);
+ d->result = QVariant::fromValue(breakpoints);
}
void QScriptDebuggerResponse::setResult(const QScriptScriptMap &scripts)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(scripts);
+ d->result = QVariant::fromValue(scripts);
}
void QScriptDebuggerResponse::setResult(const QScriptScriptData &data)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(data);
+ d->result = QVariant::fromValue(data);
}
void QScriptDebuggerResponse::setResult(const QScriptDebuggerValue &value)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(value);
+ d->result = QVariant::fromValue(value);
}
void QScriptDebuggerResponse::setResult(const QScriptDebuggerValueList &values)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(values);
+ d->result = QVariant::fromValue(values);
}
void QScriptDebuggerResponse::setResult(const QScriptDebuggerValuePropertyList &props)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(props);
+ d->result = QVariant::fromValue(props);
}
void QScriptDebuggerResponse::setResult(const QScriptContextInfo &info)
{
Q_D(QScriptDebuggerResponse);
- d->result = qVariantFromValue(info);
+ d->result = QVariant::fromValue(info);
}
int QScriptDebuggerResponse::resultAsInt() const
diff --git a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
index 117c2d60aa..83cabfdd6b 100644
--- a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
@@ -227,7 +227,7 @@ void QScriptDebuggerScriptedConsoleCommandJob::handleResponse(
QScriptEngine *engine = d->command->globalObject.engine();
engine->setGlobalObject(d->command->globalObject);
QScriptValueList args;
- args.append(qScriptValueFromValue(engine, response));
+ args.append(engine->toScriptValue(response));
args.append(QScriptValue(engine, commandId));
QScriptDebuggerConsoleGlobalObject *global;
global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(d->command->globalObject.toQObject());
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 2261887d76..a060a01947 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -420,10 +420,10 @@ QVariant QMYSQLResult::handle() const
{
#if MYSQL_VERSION_ID >= 40108
if(d->preparedQuery)
- return d->meta ? qVariantFromValue(d->meta) : qVariantFromValue(d->stmt);
+ return d->meta ? QVariant::fromValue(d->meta) : qVariantFromValue(d->stmt);
else
#endif
- return qVariantFromValue(d->result);
+ return QVariant::fromValue(d->result);
}
void QMYSQLResult::cleanup()
@@ -1432,7 +1432,7 @@ QSqlRecord QMYSQLDriver::record(const QString& tablename) const
QVariant QMYSQLDriver::handle() const
{
- return qVariantFromValue(d->mysql);
+ return QVariant::fromValue(d->mysql);
}
bool QMYSQLDriver::beginTransaction()
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index e11cf75f23..687005528d 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -293,9 +293,9 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in
SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
break;
case QVariant::UserType:
- if (qVariantCanConvert<QOCIRowIdPointer>(val) && !isOutValue(pos)) {
+ if (val.canConvert<QOCIRowIdPointer>() && !isOutValue(pos)) {
// use a const pointer to prevent a detach
- const QOCIRowIdPointer rptr = qVariantValue<QOCIRowIdPointer>(val);
+ const QOCIRowIdPointer rptr = qvariant_cast<QOCIRowIdPointer>(val);
r = OCIBindByPos(sql, hbnd, err,
pos + 1,
// it's an IN value, so const_cast is ok
@@ -1364,8 +1364,8 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
break;
}
case QVariant::UserType:
- if (qVariantCanConvert<QOCIRowIdPointer>(val)) {
- const QOCIRowIdPointer rptr = qVariantValue<QOCIRowIdPointer>(val);
+ if (val.canConvert<QOCIRowIdPointer>()) {
+ const QOCIRowIdPointer rptr = qvariant_cast<QOCIRowIdPointer>(val);
*reinterpret_cast<OCIRowid**>(dataPtr) = rptr->id;
columns[i].lengths[row] = 0;
break;
@@ -1704,7 +1704,7 @@ QOCIResult::~QOCIResult()
QVariant QOCIResult::handle() const
{
- return qVariantFromValue(d->sql);
+ return QVariant::fromValue(d->sql);
}
bool QOCIResult::reset (const QString& query)
@@ -1932,7 +1932,7 @@ QVariant QOCIResult::lastInsertId() const
int r = OCIAttrGet(d->sql, OCI_HTYPE_STMT, ptr.constData()->id,
0, OCI_ATTR_ROWID, d->err);
if (r == OCI_SUCCESS)
- return qVariantFromValue(ptr);
+ return QVariant::fromValue(ptr);
}
return QVariant();
}
@@ -2534,7 +2534,7 @@ QString QOCIDriver::formatValue(const QSqlField &field, bool trimStrings) const
QVariant QOCIDriver::handle() const
{
- return qVariantFromValue(d->env);
+ return QVariant::fromValue(d->env);
}
QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 66dabfa076..3e7777931e 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -62,15 +62,6 @@ QT_BEGIN_NAMESPACE
// undefine this to prevent initial check of the ODBC driver
#define ODBC_CHECK_DRIVER
-// newer platform SDKs use SQLLEN instead of SQLINTEGER
-#if defined(WIN32) && (_MSC_VER < 1300) && !defined(__MINGW64_VERSION_MAJOR)
-# define QSQLLEN SQLINTEGER
-# define QSQLULEN SQLUINTEGER
-#else
-# define QSQLLEN SQLLEN
-# define QSQLULEN SQLULEN
-#endif
-
static const int COLNAMESIZE = 256;
//Map Qt parameter types to ODBC types
static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT };
@@ -360,7 +351,7 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni
{
QString fieldVal;
SQLRETURN r = SQL_ERROR;
- QSQLLEN lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
// NB! colSize must be a multiple of 2 for unicode enabled DBs
if (colSize <= 0) {
@@ -462,10 +453,10 @@ static QVariant qGetBinaryData(SQLHANDLE hStmt, int column)
QByteArray fieldVal;
SQLSMALLINT colNameLen;
SQLSMALLINT colType;
- QSQLULEN colSize;
+ SQLULEN colSize;
SQLSMALLINT colScale;
SQLSMALLINT nullable;
- QSQLLEN lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
SQLRETURN r = SQL_ERROR;
QVarLengthArray<SQLTCHAR> colName(COLNAMESIZE);
@@ -499,7 +490,7 @@ static QVariant qGetBinaryData(SQLHANDLE hStmt, int column)
break;
if (lengthIndicator == SQL_NULL_DATA)
return QVariant(QVariant::ByteArray);
- if (lengthIndicator > QSQLLEN(colSize) || lengthIndicator == SQL_NO_TOTAL) {
+ if (lengthIndicator > SQLLEN(colSize) || lengthIndicator == SQL_NO_TOTAL) {
read += colSize;
colSize = 65536;
} else {
@@ -517,7 +508,7 @@ static QVariant qGetBinaryData(SQLHANDLE hStmt, int column)
static QVariant qGetIntData(SQLHANDLE hStmt, int column, bool isSigned = true)
{
SQLINTEGER intbuf = 0;
- QSQLLEN lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
SQLRETURN r = SQLGetData(hStmt,
column+1,
isSigned ? SQL_C_SLONG : SQL_C_ULONG,
@@ -537,7 +528,7 @@ static QVariant qGetIntData(SQLHANDLE hStmt, int column, bool isSigned = true)
static QVariant qGetDoubleData(SQLHANDLE hStmt, int column)
{
SQLDOUBLE dblbuf;
- QSQLLEN lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
SQLRETURN r = SQLGetData(hStmt,
column+1,
SQL_C_DOUBLE,
@@ -557,7 +548,7 @@ static QVariant qGetDoubleData(SQLHANDLE hStmt, int column)
static QVariant qGetBigIntData(SQLHANDLE hStmt, int column, bool isSigned = true)
{
SQLBIGINT lngbuf = 0;
- QSQLLEN lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
SQLRETURN r = SQLGetData(hStmt,
column+1,
isSigned ? SQL_C_SBIGINT : SQL_C_UBIGINT,
@@ -601,7 +592,7 @@ static QSqlField qMakeFieldInfo(const QODBCPrivate* p, int i )
{
SQLSMALLINT colNameLen;
SQLSMALLINT colType;
- QSQLULEN colSize;
+ SQLULEN colSize;
SQLSMALLINT colScale;
SQLSMALLINT nullable;
SQLRETURN r = SQL_ERROR;
@@ -621,7 +612,7 @@ static QSqlField qMakeFieldInfo(const QODBCPrivate* p, int i )
return QSqlField();
}
- QSQLLEN unsignedFlag = SQL_FALSE;
+ SQLLEN unsignedFlag = SQL_FALSE;
r = SQLColAttribute (p->hStmt,
i + 1,
SQL_DESC_UNSIGNED,
@@ -1146,7 +1137,7 @@ QVariant QODBCResult::data(int field)
return d->fieldCache.at(field);
SQLRETURN r(0);
- QSQLLEN lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
for (int i = d->fieldCacheIdx; i <= field; ++i) {
// some servers do not support fetching column n after we already
@@ -1256,7 +1247,7 @@ int QODBCResult::size()
int QODBCResult::numRowsAffected()
{
- QSQLLEN affectedRowCount = 0;
+ SQLLEN affectedRowCount = 0;
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
if (r == SQL_SUCCESS)
return affectedRowCount;
@@ -1343,8 +1334,8 @@ bool QODBCResult::exec()
SQLCloseCursor(d->hStmt);
QList<QByteArray> tmpStorage; // holds temporary buffers
- QVarLengthArray<QSQLLEN, 32> indicators(boundValues().count());
- memset(indicators.data(), 0, indicators.size() * sizeof(QSQLLEN));
+ QVarLengthArray<SQLLEN, 32> indicators(boundValues().count());
+ memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN));
// bind parameters - only positional binding allowed
QVector<QVariant>& values = boundValues();
@@ -1354,7 +1345,7 @@ bool QODBCResult::exec()
if (bindValueType(i) & QSql::Out)
values[i].detach();
const QVariant &val = values.at(i);
- QSQLLEN *ind = &indicators[i];
+ SQLLEN *ind = &indicators[i];
if (val.isNull())
*ind = SQL_NULL_DATA;
switch (val.type()) {
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index 2a4e5956ba..179f7bad64 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -279,7 +279,7 @@ QPSQLResult::~QPSQLResult()
QVariant QPSQLResult::handle() const
{
- return qVariantFromValue(d->result);
+ return QVariant::fromValue(d->result);
}
void QPSQLResult::cleanup()
@@ -706,7 +706,7 @@ QPSQLDriver::~QPSQLDriver()
QVariant QPSQLDriver::handle() const
{
- return qVariantFromValue(d->connection);
+ return QVariant::fromValue(d->connection);
}
bool QPSQLDriver::hasFeature(DriverFeature f) const
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 4344af4da6..e5cc614df6 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -452,7 +452,7 @@ QSqlRecord QSQLiteResult::record() const
QVariant QSQLiteResult::handle() const
{
- return qVariantFromValue(d->stmt);
+ return QVariant::fromValue(d->stmt);
}
/////////////////////////////////////////////////////////
@@ -697,7 +697,7 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const
QVariant QSQLiteDriver::handle() const
{
- return qVariantFromValue(d->access);
+ return QVariant::fromValue(d->access);
}
QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index ea476e5ac7..89f3ed315b 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -342,7 +342,7 @@ QSqlRecord QSQLite2Result::record() const
QVariant QSQLite2Result::handle() const
{
- return qVariantFromValue(d->currentMachine);
+ return QVariant::fromValue(d->currentMachine);
}
/////////////////////////////////////////////////////////
@@ -558,7 +558,7 @@ QSqlRecord QSQLite2Driver::record(const QString &tbl) const
QVariant QSQLite2Driver::handle() const
{
- return qVariantFromValue(d->access);
+ return QVariant::fromValue(d->access);
}
QString QSQLite2Driver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 2ab37deed6..1cf5fde433 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -166,7 +166,7 @@ public:
static QSqlDatabase database(const QString& name, bool open);
static void addDatabase(const QSqlDatabase &db, const QString & name);
static void removeDatabase(const QString& name);
- static void invalidateDb(const QSqlDatabase &db, const QString &name);
+ static void invalidateDb(const QSqlDatabase &db, const QString &name, bool doWarn = true);
static DriverDict &driverDict();
static void cleanConnections();
};
@@ -200,7 +200,7 @@ void QSqlDatabasePrivate::cleanConnections()
QConnectionDict::iterator it = dict->begin();
while (it != dict->end()) {
- invalidateDb(it.value(), it.key());
+ invalidateDb(it.value(), it.key(), false);
++it;
}
dict->clear();
@@ -232,9 +232,9 @@ QSqlDatabasePrivate *QSqlDatabasePrivate::shared_null()
return &n;
}
-void QSqlDatabasePrivate::invalidateDb(const QSqlDatabase &db, const QString &name)
+void QSqlDatabasePrivate::invalidateDb(const QSqlDatabase &db, const QString &name, bool doWarn)
{
- if (db.d->ref != 1) {
+ if (db.d->ref != 1 && doWarn) {
qWarning("QSqlDatabasePrivate::removeDatabase: connection '%s' is still in use, "
"all queries will cease to work.", name.toLocal8Bit().constData());
db.d->disable();
diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h
index c84f327d12..a996e889b9 100644
--- a/src/testlib/qabstracttestlogger_p.h
+++ b/src/testlib/qabstracttestlogger_p.h
@@ -95,6 +95,8 @@ public:
virtual void addMessage(MessageTypes type, const char *message,
const char *file = 0, int line = 0) = 0;
+ virtual void registerRandomSeed(unsigned int seed) = 0;
+
static void outputString(const char *msg);
static bool isTtyOutput();
};
diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp
index 1a0e737f55..59248a995c 100644
--- a/src/testlib/qplaintestlogger.cpp
+++ b/src/testlib/qplaintestlogger.cpp
@@ -384,6 +384,7 @@ namespace QTest {
}
QPlainTestLogger::QPlainTestLogger()
+: randomSeed(9), hasRandomSeed(false)
{
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
InitializeCriticalSection(&QTest::outputCriticalSection);
@@ -415,10 +416,17 @@ void QPlainTestLogger::startLogging()
QTest::qt_snprintf(buf, sizeof(buf), "Testing %s\n",
QTestResult::currentTestObjectName());
} else {
- QTest::qt_snprintf(buf, sizeof(buf),
- "********* Start testing of %s *********\n"
- "Config: Using QTest library " QTEST_VERSION_STR
- ", Qt %s\n", QTestResult::currentTestObjectName(), qVersion());
+ if (hasRandomSeed) {
+ QTest::qt_snprintf(buf, sizeof(buf),
+ "********* Start testing of %s *********\n"
+ "Config: Using QTest library " QTEST_VERSION_STR
+ ", Qt %s, Random seed %d\n", QTestResult::currentTestObjectName(), qVersion(), randomSeed);
+ } else {
+ QTest::qt_snprintf(buf, sizeof(buf),
+ "********* Start testing of %s *********\n"
+ "Config: Using QTest library " QTEST_VERSION_STR
+ ", Qt %s\n", QTestResult::currentTestObjectName(), qVersion());
+ }
}
QTest::outputMessage(buf);
}
@@ -480,4 +488,10 @@ void QPlainTestLogger::addMessage(MessageTypes type, const char *message,
QTest::printMessage(QTest::messageType2String(type), message, file, line);
}
+void QPlainTestLogger::registerRandomSeed(unsigned int seed)
+{
+ randomSeed = seed;
+ hasRandomSeed = true;
+}
+
QT_END_NAMESPACE
diff --git a/src/testlib/qplaintestlogger_p.h b/src/testlib/qplaintestlogger_p.h
index f1f1d4e0b1..9195600137 100644
--- a/src/testlib/qplaintestlogger_p.h
+++ b/src/testlib/qplaintestlogger_p.h
@@ -75,6 +75,10 @@ public:
void addMessage(MessageTypes type, const char *message,
const char *file = 0, int line = 0);
+ void registerRandomSeed(unsigned int seed);
+private:
+ unsigned int randomSeed;
+ bool hasRandomSeed;
};
QT_END_NAMESPACE
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 633d635477..aa9b2bd253 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -159,7 +159,7 @@ template<> inline char *toString(const QVariant &v)
if (!v.isNull()) {
vstring.append(',');
if (v.canConvert(QVariant::String)) {
- vstring.append(qVariantValue<QString>(v).toLatin1());
+ vstring.append(qvariant_cast<QString>(v).toLatin1());
}
else {
vstring.append("<value not representable as string>");
diff --git a/src/testlib/qtest_global.h b/src/testlib/qtest_global.h
index a78113a561..4dd0cb7f35 100644
--- a/src/testlib/qtest_global.h
+++ b/src/testlib/qtest_global.h
@@ -62,7 +62,7 @@ QT_MODULE(Test)
# endif
#endif
-#if (defined (Q_CC_MSVC) && _MSC_VER < 1310) || defined (Q_CC_SUN) || defined (Q_CC_XLC) || (defined (Q_CC_GNU) && (__GNUC__ - 0 < 3)) || defined (Q_CC_NOKIAX86)
+#if defined (Q_CC_SUN) || defined (Q_CC_XLC) || (defined (Q_CC_GNU) && (__GNUC__ - 0 < 3)) || defined (Q_CC_NOKIAX86)
# define QTEST_NO_SPECIALIZATIONS
#endif
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 17f1a6b3b0..aae2786770 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -826,25 +826,46 @@ namespace QTest
{
static QObject *currentTestObject = 0;
- static struct TestFunction {
- TestFunction():function(0), data(0) {}
- ~TestFunction() { delete [] data; }
- int function;
- char *data;
- } *testFuncs;
-
+ class TestFunction {
+ public:
+ TestFunction() : function_(-1), data_(0) {}
+ void set(int function, char *data) { function_ = function; data_ = data; }
+ char *data() const { return data_; }
+ int function() const { return function_; }
+ ~TestFunction() { delete[] data_; }
+ private:
+ int function_;
+ char *data_;
+ };
/**
- * Contains the count of test functions that was supplied
- * on the command line, if any. Hence, if lastTestFuncIdx is
- * more than zero, those functions should be run instead of
+ * Contains the list of test functions that was supplied
+ * on the command line, if any. Hence, if not empty,
+ * those functions should be run instead of
* all appearing in the test case.
*/
- static int lastTestFuncIdx = -1;
+ static TestFunction * testFuncs = 0;
+ static int testFuncCount = 0;
+
+ /** Don't leak testFuncs on exit even on error */
+ static struct TestFuncCleanup
+ {
+ void cleanup()
+ {
+ delete[] testFuncs;
+ testFuncCount = 0;
+ testFuncs = 0;
+ }
+
+ ~TestFuncCleanup() { cleanup(); }
+ } testFuncCleaner;
static int keyDelay = -1;
static int mouseDelay = -1;
static int eventDelay = -1;
+ static bool randomOrder = false;
static int keyVerbose = -1;
+ static unsigned int seed = 0;
+ static bool seedSet = false;
#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
static bool noCrashHandler = false;
#endif
@@ -930,6 +951,43 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
return keyDelay;
}
+void seedRandom()
+{
+ static bool randomSeeded = false;
+ if (!randomSeeded) {
+ if (!QTest::seedSet) {
+ QElapsedTimer timer;
+ timer.start();
+ QTest::seed = timer.msecsSinceReference();
+ }
+ qsrand(QTest::seed);
+ randomSeeded = true;
+ }
+}
+
+int qTestRandomSeed()
+{
+ Q_ASSERT(QTest::seedSet);
+ return QTest::seed;
+}
+
+template<typename T>
+void swap(T * array, int pos, int otherPos)
+{
+ T tmp = array[pos];
+ array[pos] = array[otherPos];
+ array[otherPos] = tmp;
+}
+
+template<typename T>
+static void randomizeList(T * array, int size)
+{
+ for (int i = 0; i != size; i++) {
+ int pos = qrand() % size;
+ swap(array, pos, i);
+ }
+}
+
static bool isValidSlot(const QMetaMethod &sl)
{
if (sl.access() != QMetaMethod::Private || !sl.parameterTypes().isEmpty()
@@ -971,8 +1029,6 @@ static int qToInt(char *str)
static void qParseArgs(int argc, char *argv[])
{
- lastTestFuncIdx = -1;
-
const char *testOptions =
" options:\n"
" -functions : Returns a list of current testfunctions\n"
@@ -985,6 +1041,9 @@ static void qParseArgs(int argc, char *argv[])
" -v1 : Print enter messages for each testfunction\n"
" -v2 : Also print out each QVERIFY/QCOMPARE/QTEST\n"
" -vs : Print every signal emitted\n"
+ " -random : Run testcases within each test in random order\n"
+ " -seed n : Positive integer to be used as seed for -random. If not specified,\n"
+ " the current time will be used as seed.\n"
" -eventdelay ms : Set default delay for mouse and keyboard simulation to ms milliseconds\n"
" -keydelay ms : Set default delay for keyboard simulation to ms milliseconds\n"
" -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
@@ -1100,6 +1159,22 @@ static void qParseArgs(int argc, char *argv[])
#endif
} else if (strcmp(argv[i], "-eventcounter") == 0) {
QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::EventCounter);
+ } else if (strcmp(argv[i], "-random") == 0) {
+ QTest::randomOrder = true;
+ } else if (strcmp(argv[i], "-seed") == 0) {
+ bool argumentOk = false;
+ if (i + 1 < argc) {
+ char * endpt = 0;
+ long longSeed = strtol(argv[++i], &endpt, 10);
+ argumentOk = (*endpt == '\0' && longSeed >= 0);
+ QTest::seed = longSeed;
+ }
+ if (!argumentOk) {
+ printf("-seed needs an extra positive integer parameter to specify the seed\n");
+ exit(1);
+ } else {
+ QTest::seedSet = true;
+ }
} else if (strcmp(argv[i], "-minimumvalue") == 0) {
if (i + 1 >= argc) {
printf("-minimumvalue needs an extra parameter to indicate the minimum time(ms)\n");
@@ -1140,6 +1215,10 @@ static void qParseArgs(int argc, char *argv[])
printf("Unknown option: '%s'\n\n%s", argv[i], testOptions);
exit(1);
} else {
+ if (!QTest::testFuncs) {
+ QTest::testFuncs = new QTest::TestFunction[512];
+ }
+
int colon = -1;
char buf[512], *data=0;
int off;
@@ -1161,17 +1240,16 @@ static void qParseArgs(int argc, char *argv[])
qPrintTestSlots();
exit(1);
}
- ++QTest::lastTestFuncIdx;
- if (!QTest::testFuncs) {
- struct Cleanup { ~Cleanup() { delete[] QTest::testFuncs; } };
- static Cleanup cleanup;
- QTest::testFuncs = new TestFunction[512];
- }
- QTest::testFuncs[QTest::lastTestFuncIdx].function = idx;
- QTest::testFuncs[QTest::lastTestFuncIdx].data = data;
- QTEST_ASSERT(QTest::lastTestFuncIdx < 512);
+ testFuncs[testFuncCount].set(idx, data);
+ testFuncCount++;
+ QTEST_ASSERT(QTest::testFuncCount < 512);
}
}
+
+ if (QTest::seedSet && !QTest::randomOrder) {
+ printf("-seed requires -random\n");
+ exit(1);
+ }
}
QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
@@ -1466,9 +1544,11 @@ static void qInvokeTestMethods(QObject *testObject)
{
const QMetaObject *metaObject = testObject->metaObject();
QTEST_ASSERT(metaObject);
-
- QTestLog::startLogging();
-
+ if (QTest::randomOrder) {
+ QTestLog::startLogging(QTest::seed);
+ } else {
+ QTestLog::startLogging();
+ }
QTestResult::setCurrentTestFunction("initTestCase");
QTestResult::setCurrentTestLocation(QTestResult::DataFunc);
QTestTable::globalTestTable();
@@ -1484,21 +1564,31 @@ static void qInvokeTestMethods(QObject *testObject)
if(!QTestResult::skipCurrentTest() && !previousFailed) {
- if (lastTestFuncIdx >= 0) {
- for (int i = 0; i <= lastTestFuncIdx; ++i) {
- if (!qInvokeTestMethod(metaObject->method(testFuncs[i].function).signature(),
- testFuncs[i].data))
+ if (QTest::testFuncs) {
+ if (QTest::randomOrder)
+ randomizeList(QTest::testFuncs, QTest::testFuncCount);
+ for (int i = 0; i != QTest::testFuncCount; i++) {
+ if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).signature(),
+ QTest::testFuncs[i].data())) {
break;
+ }
}
+ testFuncCleaner.cleanup();
} else {
int methodCount = metaObject->methodCount();
- for (int i = 0; i < methodCount; ++i) {
- QMetaMethod slotMethod = metaObject->method(i);
- if (!isValidSlot(slotMethod))
+ QMetaMethod *testMethods = new QMetaMethod[methodCount];
+ for (int i = 0; i != methodCount; i++)
+ testMethods[i] = metaObject->method(i);
+ if (QTest::randomOrder)
+ randomizeList(testMethods, methodCount);
+ for (int i = 0; i != methodCount; i++) {
+ if (!isValidSlot(testMethods[i]))
continue;
- if (!qInvokeTestMethod(slotMethod.signature()))
+ if (!qInvokeTestMethod(testMethods[i].signature()))
break;
}
+ delete[] testMethods;
+ testMethods = 0;
}
}
@@ -1689,6 +1779,9 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
QTestResult::setCurrentTestObject(metaObject->className());
qParseArgs(argc, argv);
+ if (QTest::randomOrder) {
+ seedRandom();
+ }
#ifdef QTESTLIB_USE_VALGRIND
if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
const QStringList origAppArgs(QCoreApplication::arguments());
diff --git a/src/testlib/qtestlightxmlstreamer.cpp b/src/testlib/qtestlightxmlstreamer.cpp
index 0ac9ea86e8..cc5397a394 100644
--- a/src/testlib/qtestlightxmlstreamer.cpp
+++ b/src/testlib/qtestlightxmlstreamer.cpp
@@ -42,6 +42,7 @@
#include "qtestlightxmlstreamer.h"
#include "qtestelement.h"
#include "qtestelementattribute.h"
+#include "qtestlogger_p.h"
#include "QtTest/private/qtestlog_p.h"
#include "QtTest/private/qtestresult_p.h"
@@ -164,8 +165,13 @@ void QTestLightXmlStreamer::formatBeforeAttributes(const QTestElement *element,
void QTestLightXmlStreamer::output(QTestElement *element) const
{
QTestCharBuffer buf;
- QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n",
+ if (logger()->hasRandomSeed()) {
+ QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n <RandomSeed>%d</RandomSeed>\n",
+ qVersion(), QTEST_VERSION_STR, logger()->randomSeed() );
+ } else {
+ QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n",
qVersion(), QTEST_VERSION_STR );
+ }
outputString(buf.constData());
QTest::qt_asprintf(&buf, "</Environment>\n");
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 398dec515e..d58e2315c2 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -168,6 +168,29 @@ namespace QTest {
}
}
+void initLogger()
+{
+ switch (QTest::logMode) {
+ case QTestLog::Plain:
+ QTest::testLogger = new QPlainTestLogger;
+ break;
+ case QTestLog::XML:{
+ if(QTest::flushMode == QTestLog::FLushOn)
+ QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete);
+ else
+ QTest::testLogger = new QTestLogger(QTestLogger::TLF_XML);
+ break;
+ }case QTestLog::LightXML:{
+ if(QTest::flushMode == QTestLog::FLushOn)
+ QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light);
+ else
+ QTest::testLogger = new QTestLogger(QTestLogger::TLF_LightXml);
+ break;
+ }case QTestLog::XunitXML:
+ QTest::testLogger = new QTestLogger(QTestLogger::TLF_XunitXml);
+ }
+}
+
}
QTestLog::QTestLog()
@@ -268,32 +291,20 @@ void QTestLog::addBenchmarkResult(const QBenchmarkResult &result)
QTest::testLogger->addBenchmarkResult(result);
}
-void QTestLog::startLogging()
+void QTestLog::startLogging(unsigned int randomSeed)
{
QTEST_ASSERT(!QTest::testLogger);
-
- switch (QTest::logMode) {
- case QTestLog::Plain:
- QTest::testLogger = new QPlainTestLogger;
- break;
- case QTestLog::XML:{
- if(QTest::flushMode == QTestLog::FLushOn)
- QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete);
- else
- QTest::testLogger = new QTestLogger(QTestLogger::TLF_XML);
- break;
- }case QTestLog::LightXML:{
- if(QTest::flushMode == QTestLog::FLushOn)
- QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light);
- else
- QTest::testLogger = new QTestLogger(QTestLogger::TLF_LightXml);
- break;
- }case QTestLog::XunitXML:
- QTest::testLogger = new QTestLogger(QTestLogger::TLF_XunitXml);
- }
-
+ QTest::initLogger();
+ QTest::testLogger->registerRandomSeed(randomSeed);
QTest::testLogger->startLogging();
+ QTest::oldMessageHandler = qInstallMsgHandler(QTest::messageHandler);
+}
+void QTestLog::startLogging()
+{
+ QTEST_ASSERT(!QTest::testLogger);
+ QTest::initLogger();
+ QTest::testLogger->startLogging();
QTest::oldMessageHandler = qInstallMsgHandler(QTest::messageHandler);
}
diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h
index d36ff0426b..01d39eb3e1 100644
--- a/src/testlib/qtestlog_p.h
+++ b/src/testlib/qtestlog_p.h
@@ -83,6 +83,7 @@ public:
static void info(const char *msg, const char *file, int line);
static void startLogging();
+ static void startLogging(unsigned int randomSeed);
static void stopLogging();
static void setLogMode(LogMode mode);
@@ -97,7 +98,6 @@ public:
static void setMaxWarnings(int max);
static void setFlushMode(FlushMode mode);
-
private:
QTestLog();
~QTestLog();
diff --git a/src/testlib/qtestlogger.cpp b/src/testlib/qtestlogger.cpp
index f0be6be4e6..cab97d16d6 100644
--- a/src/testlib/qtestlogger.cpp
+++ b/src/testlib/qtestlogger.cpp
@@ -62,7 +62,8 @@ QTestLogger::QTestLogger(int fm)
warningCounter(0), skipCounter(0),
systemCounter(0), qdebugCounter(0),
qwarnCounter(0), qfatalCounter(0),
- infoCounter(0)
+ infoCounter(0), randomSeed_(0),
+ hasRandomSeed_(false)
{
}
@@ -133,6 +134,14 @@ void QTestLogger::stopLogging()
property->addAttribute(QTest::AI_PropertyValue, qVersion());
properties->addLogElement(property);
+ if (hasRandomSeed()) {
+ property = new QTestElement(QTest::LET_Property);
+ property->addAttribute(QTest::AI_Name, "RandomSeed");
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", randomSeed());
+ property->addAttribute(QTest::AI_PropertyValue, buf);
+ properties->addLogElement(property);
+ }
+
currentLogElement->addLogElement(properties);
currentLogElement->addLogElement(iterator);
@@ -420,5 +429,21 @@ int QTestLogger::infoCount() const
return infoCounter;
}
+void QTestLogger::registerRandomSeed(unsigned int seed)
+{
+ randomSeed_ = seed;
+ hasRandomSeed_ = true;
+}
+
+unsigned int QTestLogger::randomSeed() const
+{
+ return randomSeed_;
+}
+
+bool QTestLogger::hasRandomSeed() const
+{
+ return hasRandomSeed_;
+}
+
QT_END_NAMESPACE
diff --git a/src/testlib/qtestlogger_p.h b/src/testlib/qtestlogger_p.h
index bb7a3581fb..8932a85e7d 100644
--- a/src/testlib/qtestlogger_p.h
+++ b/src/testlib/qtestlogger_p.h
@@ -101,6 +101,9 @@ class QTestLogger : public QAbstractTestLogger
int qwarnCount() const;
int qfatalCount() const;
int infoCount() const;
+ void registerRandomSeed(unsigned int seed);
+ unsigned int randomSeed() const;
+ bool hasRandomSeed() const;
private:
QTestElement *listOfTestcases;
@@ -121,6 +124,8 @@ class QTestLogger : public QAbstractTestLogger
int qwarnCounter;
int qfatalCounter;
int infoCounter;
+ unsigned int randomSeed_;
+ bool hasRandomSeed_;
};
QT_END_NAMESPACE
diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp
index 8c52a82bbc..bbe3e7feb5 100644
--- a/src/testlib/qtestresult.cpp
+++ b/src/testlib/qtestresult.cpp
@@ -191,10 +191,13 @@ bool QTestResult::expectFail(const char *dataIndex, const char *comment,
QTEST_ASSERT(comment);
QTEST_ASSERT(mode > 0);
- if (!isExpectFailData(dataIndex))
+ if (!isExpectFailData(dataIndex)) {
+ delete[] comment;
return true; // we don't care
+ }
if (QTest::expectFailMode) {
+ delete[] comment;
clearExpectFail();
addFailure("Already expecting a fail", file, line);
return false;
diff --git a/src/testlib/qtestxmlstreamer.cpp b/src/testlib/qtestxmlstreamer.cpp
index f63c2216ca..a6b8376fa5 100644
--- a/src/testlib/qtestxmlstreamer.cpp
+++ b/src/testlib/qtestxmlstreamer.cpp
@@ -42,6 +42,7 @@
#include "qtestxmlstreamer.h"
#include "qtestelement.h"
#include "qtestelementattribute.h"
+#include "qtestlogger_p.h"
#include "QtTest/private/qtestlog_p.h"
#include "QtTest/private/qtestresult_p.h"
@@ -204,8 +205,13 @@ void QTestXmlStreamer::output(QTestElement *element) const
quotedTc.constData());
outputString(buf.constData());
- QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n",
- qVersion(), QTEST_VERSION_STR );
+ if (logger()->hasRandomSeed()) {
+ QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n <RandomSeed>%d</RandomSeed>\n",
+ qVersion(), QTEST_VERSION_STR, logger()->randomSeed() );
+ } else {
+ QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n",
+ qVersion(), QTEST_VERSION_STR );
+ }
outputString(buf.constData());
QTest::qt_asprintf(&buf, "</Environment>\n");
diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp
index 07e8ef0af9..2bf7d77085 100644
--- a/src/testlib/qxmltestlogger.cpp
+++ b/src/testlib/qxmltestlogger.cpp
@@ -93,7 +93,7 @@ namespace QTest {
QXmlTestLogger::QXmlTestLogger(XmlMode mode )
- :xmlmode(mode)
+ :xmlmode(mode), randomSeed(0), hasRandomSeed(false)
{
}
@@ -116,11 +116,20 @@ void QXmlTestLogger::startLogging()
outputString(buf.constData());
}
- QTest::qt_asprintf(&buf,
- "<Environment>\n"
- " <QtVersion>%s</QtVersion>\n"
- " <QTestVersion>"QTEST_VERSION_STR"</QTestVersion>\n"
- "</Environment>\n", qVersion());
+ if (hasRandomSeed) {
+ QTest::qt_asprintf(&buf,
+ "<Environment>\n"
+ " <QtVersion>%s</QtVersion>\n"
+ " <QTestVersion>"QTEST_VERSION_STR"</QTestVersion>\n"
+ " <RandomSeed>%d</RandomSeed>\n"
+ "</Environment>\n", qVersion(), randomSeed);
+ } else {
+ QTest::qt_asprintf(&buf,
+ "<Environment>\n"
+ " <QtVersion>%s</QtVersion>\n"
+ " <QTestVersion>"QTEST_VERSION_STR"</QTestVersion>\n"
+ "</Environment>\n", qVersion());
+ }
outputString(buf.constData());
}
@@ -441,4 +450,10 @@ int QXmlTestLogger::xmlCdata(QTestCharBuffer* str, char const* src)
return allocateStringFn(str, src, QXmlTestLogger::xmlCdata);
}
+void QXmlTestLogger::registerRandomSeed(unsigned int seed)
+{
+ randomSeed = seed;
+ hasRandomSeed = true;
+}
+
QT_END_NAMESPACE
diff --git a/src/testlib/qxmltestlogger_p.h b/src/testlib/qxmltestlogger_p.h
index ae918dcc54..82dd8a64c4 100644
--- a/src/testlib/qxmltestlogger_p.h
+++ b/src/testlib/qxmltestlogger_p.h
@@ -79,6 +79,8 @@ public:
void addMessage(MessageTypes type, const char *message,
const char *file = 0, int line = 0);
+ void registerRandomSeed(unsigned int seed);
+
static int xmlCdata(QTestCharBuffer *dest, char const* src);
static int xmlQuote(QTestCharBuffer *dest, char const* src);
static int xmlCdata(QTestCharBuffer *dest, char const* src, size_t n);
@@ -86,6 +88,8 @@ public:
private:
XmlMode xmlmode;
+ unsigned int randomSeed;
+ bool hasRandomSeed;
};
QT_END_NAMESPACE
diff --git a/src/tools/bootstrap/bootstrap.pri b/src/tools/bootstrap/bootstrap.pri
index 1aa812116f..f48c8c12ff 100644
--- a/src/tools/bootstrap/bootstrap.pri
+++ b/src/tools/bootstrap/bootstrap.pri
@@ -22,7 +22,9 @@ DEFINES += \
QT_NO_TEXTSTREAM \
QT_NO_THREAD \
QT_NO_UNICODETABLES \
- QT_NO_USING_NAMESPACE
+ QT_NO_USING_NAMESPACE \
+ QT_NO_DEPRECATED
+
win32:DEFINES += QT_NODLL
INCLUDEPATH += $$QT_BUILD_TREE/include \
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index ba844ea074..27b733633d 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -25,7 +25,9 @@ DEFINES += \
QT_NO_TEXTSTREAM \
QT_NO_THREAD \
QT_NO_UNICODETABLES \
- QT_NO_USING_NAMESPACE
+ QT_NO_USING_NAMESPACE \
+ QT_NO_DEPRECATED
+
win32:DEFINES += QT_NODLL
INCLUDEPATH += $$QT_BUILD_TREE/include \
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index b06eb7a27e..a2bc89d7bc 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -139,13 +139,17 @@ namespace {
<< indent << "QWidgetList childWidgets;\n";
}
- static inline bool isIconFormat44(const DomResourceIcon *i) {
+ static inline bool iconHasStatePixmaps(const DomResourceIcon *i) {
return i->hasElementNormalOff() || i->hasElementNormalOn() ||
i->hasElementDisabledOff() || i->hasElementDisabledOn() ||
i->hasElementActiveOff() || i->hasElementActiveOn() ||
i->hasElementSelectedOff() || i->hasElementSelectedOn();
}
+ static inline bool isIconFormat44(const DomResourceIcon *i) {
+ return iconHasStatePixmaps(i) || !i->attributeTheme().isEmpty();
+ }
+
// Check on properties. Filter out empty legacy pixmap/icon properties
// as Designer pre 4.4 used to remove missing resource references.
// This can no longer be handled by the code as we have 'setIcon(QIcon())' as well as 'QIcon icon'
@@ -258,6 +262,9 @@ IconHandle::IconHandle(const DomResourceIcon *domIcon) :
int IconHandle::compare(const IconHandle &rhs) const
{
+ if (const int comp = m_domIcon->attributeTheme().compare(rhs.m_domIcon->attributeTheme()))
+ return comp;
+
const QString normalOff = m_domIcon->hasElementNormalOff() ? m_domIcon->elementNormalOff()->text() : QString();
const QString rhsNormalOff = rhs.m_domIcon->hasElementNormalOff() ? rhs.m_domIcon->elementNormalOff()->text() : QString();
if (const int comp = normalOff.compare(rhsNormalOff))
@@ -478,7 +485,8 @@ WriteInitialization::WriteInitialization(Uic *uic, bool activateScripts) :
m_delayedOut(&m_delayedInitialization, QIODevice::WriteOnly),
m_refreshOut(&m_refreshInitialization, QIODevice::WriteOnly),
m_actionOut(&m_delayedActionInitialization, QIODevice::WriteOnly),
- m_activateScripts(activateScripts), m_layoutWidget(false)
+ m_activateScripts(activateScripts), m_layoutWidget(false),
+ m_firstThemeIcon(true)
{
}
@@ -1670,6 +1678,30 @@ QString WriteInitialization::writeFontProperties(const DomFont *f)
return fontName;
}
+// Post 4.4 write resource icon
+static void writeResourceIcon(QTextStream &output,
+ const QString &iconName,
+ const QString &indent,
+ const DomResourceIcon *i)
+{
+ if (i->hasElementNormalOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::Off);\n";
+ if (i->hasElementNormalOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOn()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::On);\n";
+ if (i->hasElementDisabledOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOff()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::Off);\n";
+ if (i->hasElementDisabledOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOn()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::On);\n";
+ if (i->hasElementActiveOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOff()->text(), indent) << "), QSize(), QIcon::Active, QIcon::Off);\n";
+ if (i->hasElementActiveOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOn()->text(), indent) << "), QSize(), QIcon::Active, QIcon::On);\n";
+ if (i->hasElementSelectedOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOff()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::Off);\n";
+ if (i->hasElementSelectedOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOn()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::On);\n";
+}
+
QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
{
// check cache
@@ -1683,25 +1715,41 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
const QString iconName = m_driver->unique(QLatin1String("icon"));
m_iconPropertiesNameMap.insert(IconHandle(i), iconName);
if (isIconFormat44(i)) {
- const QString pixmap = QLatin1String("QPixmap");
- m_output << m_indent << "QIcon " << iconName << ";\n";
- if (i->hasElementNormalOff())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Normal, QIcon::Off);\n";
- if (i->hasElementNormalOn())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOn()->text(), m_dindent) << "), QSize(), QIcon::Normal, QIcon::On);\n";
- if (i->hasElementDisabledOff())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOff()->text(), m_dindent) << "), QSize(), QIcon::Disabled, QIcon::Off);\n";
- if (i->hasElementDisabledOn())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOn()->text(), m_dindent) << "), QSize(), QIcon::Disabled, QIcon::On);\n";
- if (i->hasElementActiveOff())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOff()->text(), m_dindent) << "), QSize(), QIcon::Active, QIcon::Off);\n";
- if (i->hasElementActiveOn())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOn()->text(), m_dindent) << "), QSize(), QIcon::Active, QIcon::On);\n";
- if (i->hasElementSelectedOff())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOff()->text(), m_dindent) << "), QSize(), QIcon::Selected, QIcon::Off);\n";
- if (i->hasElementSelectedOn())
- m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOn()->text(), m_dindent) << "), QSize(), QIcon::Selected, QIcon::On);\n";
- } else { // pre-4.4 legacy
+ if (i->attributeTheme().isEmpty()) {
+ // No theme: Write resource icon as is
+ m_output << m_indent << "QIcon " << iconName << ";\n";
+ writeResourceIcon(m_output, iconName, m_indent, i);
+ } else {
+ // Theme: Generate code to check the theme and default to resource
+ const QString themeIconName = fixString(i->attributeTheme(), QString());
+ if (iconHasStatePixmaps(i)) {
+ // Theme + default state pixmaps:
+ // Generate code to check the theme and default to state pixmaps
+ m_output << m_indent << "QIcon " << iconName << ";\n";
+ const char themeNameStringVariableC[] = "iconThemeName";
+ // Store theme name in a variable
+ m_output << m_indent;
+ if (m_firstThemeIcon) { // Declare variable string
+ m_output << "QString ";
+ m_firstThemeIcon = false;
+ }
+ m_output << themeNameStringVariableC << " = QString::fromUtf8("
+ << themeIconName << ");\n";
+ m_output << m_indent << "if (QIcon::hasThemeIcon("
+ << themeNameStringVariableC
+ << ")) {\n"
+ << m_dindent << iconName << " = QIcon::fromTheme(" << themeNameStringVariableC << ");\n"
+ << m_indent << "} else {\n";
+ writeResourceIcon(m_output, iconName, m_dindent, i);
+ m_output << m_indent << "}\n";
+ } else {
+ // Theme, but no state pixmaps: Construct from theme directly.
+ m_output << m_indent << "QIcon " << iconName
+ << "(QIcon::fromTheme(QString::fromUtf8("
+ << themeIconName << ")));\n";
+ } // Theme, but not state
+ } // >= 4.4
+ } else { // pre-4.4 legacy
m_output << m_indent << "const QIcon " << iconName << " = " << pixCall(QLatin1String("QIcon"), i->text())<< ";\n";
}
return iconName;
diff --git a/src/tools/uic/cpp/cppwriteinitialization.h b/src/tools/uic/cpp/cppwriteinitialization.h
index 7507166f77..b9cf2cd3f5 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.h
+++ b/src/tools/uic/cpp/cppwriteinitialization.h
@@ -363,6 +363,7 @@ private:
const bool m_activateScripts;
bool m_layoutWidget;
+ bool m_firstThemeIcon;
};
} // namespace CPP
diff --git a/src/tools/uic/ui4.cpp b/src/tools/uic/ui4.cpp
index e80523f1f8..19886967b8 100644
--- a/src/tools/uic/ui4.cpp
+++ b/src/tools/uic/ui4.cpp
@@ -7745,6 +7745,7 @@ void DomResourceIcon::clear(bool clear_all)
if (clear_all) {
m_text = QLatin1String("");
+ m_has_attr_theme = false;
m_has_attr_resource = false;
}
@@ -7762,6 +7763,7 @@ void DomResourceIcon::clear(bool clear_all)
DomResourceIcon::DomResourceIcon()
{
m_children = 0;
+ m_has_attr_theme = false;
m_has_attr_resource = false;
m_text = QLatin1String("");
m_normalOff = 0;
@@ -7791,6 +7793,10 @@ void DomResourceIcon::read(QXmlStreamReader &reader)
foreach (const QXmlStreamAttribute &attribute, reader.attributes()) {
QStringRef name = attribute.name();
+ if (name == QLatin1String("theme")) {
+ setAttributeTheme(attribute.value().toString());
+ continue;
+ }
if (name == QLatin1String("resource")) {
setAttributeResource(attribute.value().toString());
continue;
@@ -7869,6 +7875,8 @@ void DomResourceIcon::read(QXmlStreamReader &reader)
#ifdef QUILOADER_QDOM_READ
void DomResourceIcon::read(const QDomElement &node)
{
+ if (node.hasAttribute(QLatin1String("theme")))
+ setAttributeTheme(node.attribute(QLatin1String("theme")));
if (node.hasAttribute(QLatin1String("resource")))
setAttributeResource(node.attribute(QLatin1String("resource")));
@@ -7938,6 +7946,9 @@ void DomResourceIcon::write(QXmlStreamWriter &writer, const QString &tagName) co
{
writer.writeStartElement(tagName.isEmpty() ? QString::fromUtf8("resourceicon") : tagName.toLower());
+ if (hasAttributeTheme())
+ writer.writeAttribute(QLatin1String("theme"), attributeTheme());
+
if (hasAttributeResource())
writer.writeAttribute(QLatin1String("resource"), attributeResource());
diff --git a/src/tools/uic/ui4.h b/src/tools/uic/ui4.h
index 1f38f887f5..a464a89516 100644
--- a/src/tools/uic/ui4.h
+++ b/src/tools/uic/ui4.h
@@ -2809,6 +2809,11 @@ public:
inline void setText(const QString &s) { m_text = s; }
// attribute accessors
+ inline bool hasAttributeTheme() const { return m_has_attr_theme; }
+ inline QString attributeTheme() const { return m_attr_theme; }
+ inline void setAttributeTheme(const QString& a) { m_attr_theme = a; m_has_attr_theme = true; }
+ inline void clearAttributeTheme() { m_has_attr_theme = false; }
+
inline bool hasAttributeResource() const { return m_has_attr_resource; }
inline QString attributeResource() const { return m_attr_resource; }
inline void setAttributeResource(const QString& a) { m_attr_resource = a; m_has_attr_resource = true; }
@@ -2868,6 +2873,9 @@ private:
void clear(bool clear_all = true);
// attribute data
+ QString m_attr_theme;
+ bool m_has_attr_theme;
+
QString m_attr_resource;
bool m_has_attr_resource;
diff --git a/src/tools/uic3/converter.cpp b/src/tools/uic3/converter.cpp
index 2ee939d069..8fac4d160d 100644
--- a/src/tools/uic3/converter.cpp
+++ b/src/tools/uic3/converter.cpp
@@ -864,7 +864,7 @@ DomLayoutItem *Ui3Reader::createLayoutItem(const QDomElement &e)
Variant var;
var.createSize(0, 0);
- QVariant def = qVariantFromValue(var);
+ QVariant def = QVariant::fromValue(var);
Size size = asVariant(DomTool::readProperty(e, QLatin1String("sizeHint"), def)).size;
QString sizeType = QLatin1String("QSizePolicy::") + DomTool::readProperty(e, QLatin1String("sizeType"), QLatin1String("Expanding")).toString();
diff --git a/src/tools/uic3/domtool.cpp b/src/tools/uic3/domtool.cpp
index 526b41cbe8..cefbbb4090 100644
--- a/src/tools/uic3/domtool.cpp
+++ b/src/tools/uic3/domtool.cpp
@@ -169,7 +169,7 @@ QVariant DomTool::elementToVariant(const QDomElement& e, const QVariant& defValu
n3 = n3.nextSibling().toElement();
}
var.createRect(x, y, w, h);
- qVariantSetValue(v, var);
+ v.setValue(var);
} else if (e.tagName() == QLatin1String("point")) {
QDomElement n3 = e.firstChild().toElement();
int x = 0, y = 0;
@@ -181,7 +181,7 @@ QVariant DomTool::elementToVariant(const QDomElement& e, const QVariant& defValu
n3 = n3.nextSibling().toElement();
}
var.createPoint(x,y);
- qVariantSetValue(v, var);
+ v.setValue(var);
} else if (e.tagName() == QLatin1String("size")) {
QDomElement n3 = e.firstChild().toElement();
int w = 0, h = 0;
@@ -193,10 +193,10 @@ QVariant DomTool::elementToVariant(const QDomElement& e, const QVariant& defValu
n3 = n3.nextSibling().toElement();
}
var.createSize(w, h);
- qVariantSetValue(v, var);
+ v.setValue(var);
} else if (e.tagName() == QLatin1String("color")) {
var.color = readColor(e);
- qVariantSetValue(v, var);
+ v.setValue(var);
} else if (e.tagName() == QLatin1String("font")) {
QDomElement n3 = e.firstChild().toElement();
Font f;
@@ -217,7 +217,7 @@ QVariant DomTool::elementToVariant(const QDomElement& e, const QVariant& defValu
n3 = n3.nextSibling().toElement();
}
var.font = f;
- qVariantSetValue(v, var);
+ v.setValue(var);
} else if (e.tagName() == QLatin1String("string")) {
v = QVariant(e.firstChild().toText().data());
QDomElement n = e;
@@ -258,10 +258,10 @@ QVariant DomTool::elementToVariant(const QDomElement& e, const QVariant& defValu
var.sizePolicy.verstretch = n3.firstChild().toText().data().toInt();
n3 = n3.nextSibling().toElement();
}
- qVariantSetValue(v, var);
+ v.setValue(var);
} else if (e.tagName() == QLatin1String("cursor")) {
var.createCursor(e.firstChild().toText().data().toInt());
- qVariantSetValue(v, var);
+ v.setValue(var);
} else if (e.tagName() == QLatin1String("stringlist")) {
QStringList lst;
QDomElement n;
diff --git a/src/tools/uic3/domtool.h b/src/tools/uic3/domtool.h
index ad597a181d..8fe07930e3 100644
--- a/src/tools/uic3/domtool.h
+++ b/src/tools/uic3/domtool.h
@@ -266,7 +266,7 @@ QT_BEGIN_NAMESPACE
inline Variant asVariant(const QVariant &v)
{
Variant var;
- var = qVariantValue<Variant>(v);
+ var = qvariant_cast<Variant>(v);
return var;
}
diff --git a/src/xmlpatterns/api/quriloader.cpp b/src/xmlpatterns/api/quriloader.cpp
index e0a75422c1..c653661184 100644
--- a/src/xmlpatterns/api/quriloader.cpp
+++ b/src/xmlpatterns/api/quriloader.cpp
@@ -69,7 +69,7 @@ QNetworkReply *URILoader::createRequest(Operation op, const QNetworkRequest &req
const QVariant variant(m_variableLoader->valueFor(m_namePool->allocateQName(QString(), name, QString())));
if(!variant.isNull() && variant.userType() == qMetaTypeId<QIODevice *>())
- return new QIODeviceDelegate(qVariantValue<QIODevice *>(variant));
+ return new QIODeviceDelegate(qvariant_cast<QIODevice *>(variant));
else
{
/* If we're entering this code path, the variable URI identified a variable
diff --git a/src/xmlpatterns/api/qvariableloader.cpp b/src/xmlpatterns/api/qvariableloader.cpp
index 612fa6779d..648fda4e6a 100644
--- a/src/xmlpatterns/api/qvariableloader.cpp
+++ b/src/xmlpatterns/api/qvariableloader.cpp
@@ -131,12 +131,12 @@ SequenceType::Ptr VariableLoader::announceExternalVariable(const QXmlName name,
return CommonSequenceTypes::ExactlyOneAnyURI;
else if(variant.userType() == qMetaTypeId<QXmlQuery>())
{
- const QXmlQuery variableQuery(qVariantValue<QXmlQuery>(variant));
+ const QXmlQuery variableQuery(qvariant_cast<QXmlQuery>(variant));
return variableQuery.d->expression()->staticType();
}
else
{
- return makeGenericSequenceType(AtomicValue::qtToXDMType(qVariantValue<QXmlItem>(variant)),
+ return makeGenericSequenceType(AtomicValue::qtToXDMType(qvariant_cast<QXmlItem>(variant)),
Cardinality::exactlyOne());
}
}
@@ -154,12 +154,12 @@ Item::Iterator::Ptr VariableLoader::evaluateSequence(const QXmlName name,
return makeSingletonIterator(itemForName(name));
else if(variant.userType() == qMetaTypeId<QXmlQuery>())
{
- const QXmlQuery variableQuery(qVariantValue<QXmlQuery>(variant));
+ const QXmlQuery variableQuery(qvariant_cast<QXmlQuery>(variant));
return variableQuery.d->expression()->evaluateSequence(DynamicContext::Ptr(new TemporaryTreesRedirectingContext(variableQuery.d->dynamicContext(), context)));
}
- const QVariant v(qVariantValue<QXmlItem>(variant).toAtomicValue());
+ const QVariant v(qvariant_cast<QXmlItem>(variant).toAtomicValue());
switch(v.type())
{
@@ -179,7 +179,7 @@ Item VariableLoader::itemForName(const QXmlName &name) const
if(variant.userType() == qMetaTypeId<QIODevice *>())
return Item(AnyURI::fromValue(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + m_namePool->stringForLocalName(name.localName())));
- const QXmlItem item(qVariantValue<QXmlItem>(variant));
+ const QXmlItem item(qvariant_cast<QXmlItem>(variant));
if(item.isNode())
return Item::fromPublic(item);
@@ -210,8 +210,8 @@ bool VariableLoader::isSameType(const QVariant &v1,
return true;
/* Ok, we have two QXmlItems. */
- const QXmlItem i1(qVariantValue<QXmlItem>(v1));
- const QXmlItem i2(qVariantValue<QXmlItem>(v2));
+ const QXmlItem i1(qvariant_cast<QXmlItem>(v1));
+ const QXmlItem i2(qvariant_cast<QXmlItem>(v2));
if(i1.isNode())
{
diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp
index 55af49b451..4d6a3b64b3 100644
--- a/src/xmlpatterns/api/qxmlquery.cpp
+++ b/src/xmlpatterns/api/qxmlquery.cpp
@@ -534,7 +534,7 @@ void QXmlQuery::bindVariable(const QXmlName &name, const QXmlItem &value)
}
const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
- const QVariant variant(qVariantFromValue(value));
+ const QVariant variant(QVariant::fromValue(value));
/* If the type of the variable changed(as opposed to only the value),
* we will have to recompile. */
@@ -610,7 +610,7 @@ void QXmlQuery::bindVariable(const QXmlName &name, QIODevice *device)
if(device)
{
- const QVariant variant(qVariantFromValue(device));
+ const QVariant variant(QVariant::fromValue(device));
if(vl->invalidationRequired(name, variant))
d->recompileRequired();
@@ -1184,7 +1184,7 @@ void QXmlQuery::bindVariable(const QXmlName &name, const QXmlQuery &query)
Q_ASSERT_X(query.isValid(), Q_FUNC_INFO, "The query being bound must be valid.");
const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
- const QVariant variant(qVariantFromValue(query));
+ const QVariant variant(QVariant::fromValue(query));
if(vl->invalidationRequired(name, variant))
d->recompileRequired();
diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp
index c4f3578478..5bb9a4f91e 100644
--- a/src/xmlpatterns/data/qatomicvalue.cpp
+++ b/src/xmlpatterns/data/qatomicvalue.cpp
@@ -121,7 +121,7 @@ QVariant AtomicValue::toQt(const AtomicValue *const value)
|| BuiltinTypes::xsHexBinary->xdtTypeMatches(t))
return QVariant(value->as<Base64Binary>()->asByteArray());
else if(BuiltinTypes::xsQName->xdtTypeMatches(t))
- return qVariantFromValue(value->as<QNameValue>()->qName());
+ return QVariant::fromValue(value->as<QNameValue>()->qName());
else
{
/* A type we don't support in Qt. Includes xs:time currently. */
diff --git a/src/xmlpatterns/utils/qautoptr_p.h b/src/xmlpatterns/utils/qautoptr_p.h
index 060e7beb99..173999f513 100644
--- a/src/xmlpatterns/utils/qautoptr_p.h
+++ b/src/xmlpatterns/utils/qautoptr_p.h
@@ -122,7 +122,6 @@ namespace QPatternist
return *this;
}
-#ifndef QT_NO_MEMBER_TEMPLATES
template<typename L>
operator AutoPtrRef<L>()
{
@@ -139,7 +138,6 @@ namespace QPatternist
inline AutoPtr(AutoPtr<L>& other) : m_ptr(other.release())
{
}
-#endif
inline T *release()
{